Печать содержимого XML-файла с использованием XML DOM

У меня есть простой XML-документ:

<?xml version="1.0"?> <cellphones> <telefon> <model>Easy DB</model> <proizvodjac>Alcatel</proizvodjac> <cena>25</cena> </telefon> <telefon> <model>3310</model> <proizvodjac>Nokia</proizvodjac> <cena>30</cena> </telefon> <telefon> <model>GF768</model> <proizvodjac>Ericsson</proizvodjac> <cena>15</cena> </telefon> <telefon> <model>Skeleton</model> <proizvodjac>Panasonic</proizvodjac> <cena>45</cena> </telefon> <telefon> <model>Earl</model> <proizvodjac>Sharp</proizvodjac> <cena>60</cena> </telefon> </cellphones> 

Мне нужно распечатать содержимое этого файла с помощью XML DOM, и его необходимо структурировать следующим образом:

 "model: Easy DB proizvodjac: Alcatel cena: 25" 

для каждого узла внутри XML.

ЭТО ДОЛЖНО СДЕЛАТЬ, используя XML DOM. Это проблема. Я могу сделать это обычным, простым способом. Но это беспокоит меня, потому что я не могу найти какое-либо решение в Интернете.

Это насколько я могу идти, но мне нужно получить доступ к внутренним узлам (дочерние узлы) и получить значения узлов. Я также хочу избавиться от какой-то странной строки «#text», которая появляется неожиданно.

 <?php //kreira se DOMDocument objekat $xmlDoc = new DOMDocument(); //u xml objekat se ucitava xml fajl $xmlDoc->load("poruke.xml"); //dodeljuje se promenljivoj koreni element $x = $xmlDoc->documentElement; //prolazi se kroz petlju tako sto se ispisuje informacija o podelementima foreach ($x->childNodes AS $item){ print $item->nodeName . " = " . $item->nodeValue . "<br />"; } ?> 

благодаря

Объяснение для странных строк #text

Странные строки #text не выходят из синего цвета, но являются реальными текстовыми узлами. Когда вы загружаете форматированный XML-документ с DOM любыми пробелами, например, отступы, DOMText и значения узлов будут являться частью DOM как экземпляры DOMText по умолчанию, например

 <cellphones>\n\t<telefon>\n\t\t<model>Easy DB… ETETET 

где E – DOMElement а T – DOMText .

Чтобы обойти это, загрузите документ следующим образом:

 $dom = new DOMDocument; $dom->preserveWhiteSpace = FALSE; $dom->load('file.xml'); 

Затем ваш документ будет структурирован следующим образом

 <cellphones><telefon><model>Easy DB… EEET 

Обратите внимание, что отдельные узлы, представляющие значение DOMElement все равно будут экземплярами DOMText , но узлы, которые управляют форматированием, исчезли. Об этом позже.

доказательство

Вы можете легко проверить это с помощью этого кода:

 $dom = new DOMDocument; $dom->preserveWhiteSpace = TRUE; // change to FALSE to see the difference $dom->load('file.xml'); foreach ($dom->getElementsByTagName('telefon') as $telefon) { foreach($telefon->childNodes as $node) { printf( "Name: %s - Type: %s - Value: %s\n", $node->nodeName, $node->nodeType, urlencode($node->nodeValue) ); } } 

Этот код проходит через все элементы телефона в вашем XML и печатает имя узла, тип и значение urlencoded node его дочерних узлов. Когда вы сохраните пробелы, вы получите что-то вроде

 Name: #text - Type: 3 - Value: %0A++++ Name: model - Type: 1 - Value: Easy+DB Name: #text - Type: 3 - Value: %0A++++ Name: proizvodjac - Type: 1 - Value: Alcatel Name: #text - Type: 3 - Value: %0A++++ Name: cena - Type: 1 - Value: 25 Name: #text - Type: 3 - Value: %0A++ … 

Причина, по которой я присвоил значение, – показать, что на самом деле DOMText узлы DOMText содержащие отступы и DOMDocument в вашем DOMDocument . %0A – это разрыв линии, а каждый + – это пробел.

Когда вы сравните это с вашим XML, вы увидите, что после каждого элемента <telefon> происходит разрыв строки, за которым следуют четыре пробела, пока не начнется элемент <model> . Аналогично, между закрывающей <cena> и открытием <telefon> есть только новая строка и два пробела.

Данный тип для этих узлов равен 3, что – согласно списку предопределенных констант – это XML_TEXT_NODE , например узел DOMText . При отсутствии правильного имени элемента эти узлы имеют имя #text.

Пренебрежение пробелами

Теперь, когда вы отключите сохранение пробелов, вышесказанное выведет:

 Name: model - Type: 1 - Value: Easy+DB Name: proizvodjac - Type: 1 - Value: Alcatel Name: cena - Type: 1 - Value: 25 Name: model - Type: 1 - Value: 3310 … 

Как вы можете видеть, больше нет узлов #text, а только узлов типа 1, что означает XML_ELEMENT_NODE , например DOMElement .

DOMElements содержат узлы DOMText

В начале я сказал, что значения DOMElements являются экземплярами DOMText . Но в выводе выше их нигде не видно. Это потому, что мы получаем доступ к свойству nodeValue , которое возвращает значение DOMText как строку. Мы можем доказать, что это значение DOMText легко, хотя:

 $dom = new DOMDocument; $dom->preserveWhiteSpace = FALSE; $dom->loadXML($xml); foreach ($dom->getElementsByTagName('telefon') as $telefon) { $node = $telefon->firstChild->firstChild; // 1st child of model printf( "Name: %s - Type: %s - Value: %s\n", $node->nodeName, $node->nodeType, urlencode($node->nodeValue) ); } 

выйдет

 Name: #text - Type: 3 - Value: Easy+DB Name: #text - Type: 3 - Value: 3310 Name: #text - Type: 3 - Value: GF768 Name: #text - Type: 3 - Value: Skeleton Name: #text - Type: 3 - Value: Earl 

И это доказывает, что DOMElement содержит его значение как DOMText а nodeValue просто возвращает содержимое DOMText напрямую.

Больше на nodeValue

На самом деле nodeValue достаточно умен, чтобы DOMText содержимое любых DOMText :

 $dom = new DOMDocument; $dom->loadXML('<root><p>Hello <em>World</em>!!!</p></root>'); $node = $dom->documentElement->firstChild; // p printf( "Name: %s - Type: %s - Value: %s\n", $node->nodeName, $node->nodeType, $node->nodeValue ); 

выйдет

 Name: p - Type: 1 - Value: Hello World!!! 

хотя это действительно совокупные значения

 DOMText "Hello" DOMElement em with DOMText "World" DOMText "!!!" 

Печать содержимого XML-файла с использованием XML DOM

Чтобы наконец ответить на ваш вопрос, посмотрите на первый тестовый код. Там вам нужно все, что вам нужно. И, конечно, к тому времени вам также дали хорошие ответы.

Мне кажется, что вы хотите что-то вроде этого:

 <?php $dom = new DOMDocument(); $dom->load("poruke.xml"); $telefon = $dom->getElementsByTagName('telefon'); foreach ($telefon as $t) { print "model: " . $t->childNodes->item(0)->nodeValue . "\n" . "proizvodjac: " . $t->childNodes->item(1)->nodeValue . "\n" . "cena: " . $t->childNodes->item(2)->nodeValue; } 

Это может быть не совсем то, что вам нужно с точки зрения форматирования, но оно должно показать вам примерно то, что вам нужно сделать.

Это решение, проверено и проверено.

 <?php $xmlDoc = new DOMDocument(); $xmlDoc->load("mobiles.xml"); $x = $xmlDoc->documentElement; $telefons = $x->getElementsByTagName( "telefon" ); foreach( $telefons as $telefon ) { $model = $telefon->getElementsByTagName( "model" ); $proiz = $telefon->getElementsByTagName( "proizvodjac" ); $cena = $telefon->getElementsByTagName( "cena" ); echo $model->item(0)->nodeName .': '. $model->item(0)->nodeValue.' <br> '.$proiz->item(0)->nodeName .':'.$proiz->item(0)->nodeValue.'<br> '.$cena->item(0)->nodeName.':'.$cena->item(0)->nodeValue.' <br><br>'; } ?> 

Попробуйте

 $xmlDoc = new DOMDocument(); $dom->load("poruke.xml"); // Load the DomDoc into an Xpath object, you can then query it $xpath = new DOMXpath($xmlDoc); // Find all telefon elements $result = $xpath->query("//telefon"); // For each telefon item found foreach ($result AS $item){ // For each child node of the telefon element print the nodeName and nodeValue foreach($item->childNodes as $node){ echo $node->nodeName . " = " . $node->nodeValue . " <br />"; } } 

Нашел довольно простой способ:

 $xml = $domElement->ownerDocument->saveXML($domElement); 

или если вы уже держите документ в переменной.

 $xml = $document->saveXML($domElement); 

решение найдено по адресу: http://php.net/manual/fr/class.domelement.php