Найти конкретный элемент и его значение с помощью XPath в XML PHP - PullRequest
0 голосов
/ 04 июля 2019

Я совершенно новичок в XPath , так что будьте спокойны со мной; -)

Я пытаюсь получить контент с узла

Структура XMLвыглядит (упрощенно OOXML):

 <w:p>
     <w:r>
         <w:drawing>
             <wp:anchor wp14:editId="3BCCBF8F" wp14:anchorId="1109B0B5" 
             distR="114300" distL="114300" distB="0" distT="0" 
             allowOverlap="1" layoutInCell="1" locked="0" behindDoc="0" 
             relativeHeight="251663360" simplePos="0">
                 <a:graphic a="{url}">
                     <a:graphicData uri="{urli}">
                         <pic:pic xmlns:pic="{uri}">
                             <pic:blipFill>
                                 <a:blip cstate="print" r:embed="rId13"/>
{all closing tag p, r, w etc}

 <w:p>
     <w:r>
         <w:drawing>
             <wp:anchor wp14:editId="3BCCBF8F" wp14:anchorId="1109B0B5" 
             distR="114300" distL="114300" distB="0" distT="0" 
             allowOverlap="1" layoutInCell="1" locked="0" behindDoc="0" 
             relativeHeight="251663360" simplePos="0">
                 <a:graphic a="{url}">
                     <a:graphicData uri="{urli}">
                         <pic:pic xmlns:pic="{uri}">
                             <pic:blipFill>
                                 <a:blip cstate="print" r:embed="rId14"/>
{all closing tag p, r, w etc}

Мой код выглядит так:

$result ниже просто строка с xml

$document = new DOMDocument();
$document->loadXML($result);
$xpath = new DOMXpath($document);

$xpath->registerNamespace(
   'word', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'
                    );

foreach ($xpath->evaluate('//word:drawing//word:anchor') as $index => $node) {
    var_dump($node);
} 

Я получаюпустой узел.Я явно делаю что-то не так.Я ожидаю узел привязки с этим кодом.

Я мог бы в основном циклически бросать каждый узел и находить дочерние элементы для каждого узла, , но это, кажется, потрачено впустую XPath ...

Что-то вроде:

foreach ($xpath->evaluate('//word:drawing') as $index => $node) {
    foreach($xpath->evaluate('*', $node) as $anchornode) {
        var_dump($anchornode);
    } 
}   

Что я действительно хочу сделать, это получить значения r: embed в элементе рисунка (rId13 и rId14)

Я пытался найти то, что я хочу, в других вопросах здесь, на SO (их много) .... Если вы найдете такой вопрос, просто направьте меня на этот вопрос, пожалуйста.

1 Ответ

1 голос
/ 04 июля 2019

wp:anchor находится в другом пространстве имен (из w:document).Ищите атрибут xmlns:wp.Это определение пространства имен для префикса wp.

Вы также должны зарегистрировать псевдоним / префикс для этого пространства имен.

$xpath->registerNamespace(
   'word', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'
);    
$xpath->registerNamespace(
   'wp', 'urn:???'
);

Ваш код регистрирует префикс word для URI пространства имен http://schemas.openxmlformats.org/wordprocessingml/2006/main

Это позволяет процессору Xpath разрешать префикс в выражении Xpath.Вы можете прочитать это как:

//word:drawing -> //{http://schemas.openxmlformats.org/wordprocessingml/2006/main}drawing

Синтаксический анализатор XML делает то же самое с именами узлов.

<w:drawing/> -> <{http://schemas.openxmlformats.org/wordprocessingml/2006/main}drawing/>

Так оно и есть.Но потому что что-то подобное было бы действительно трудно читать (для людей) и приводить к большим файлам XML, используются псевдонимы / префиксы.Вы можете использовать те же префиксы, что и в документе (w, wp, ...) в выражениях Xpath, но вам придется зарегистрировать их в тех же URI пространства имен.Думайте о префиксах как об именах переменных, сохраняйте их читаемыми, чтобы вы могли понять свой код позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...