使用XML DOM打印XML文件的内容

时间:2011-01-04 21:04:51

标签: php 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 />";
    }
?>

由于

5 个答案:

答案 0 :(得分:6)

对奇怪的#text字符串的解释

奇怪的#text字符串不是蓝色的,而是实际的文本节点。当您使用DOM任何空格加载带格式的XML文档时,例如默认情况下,缩进,换行符和节点值将作为DOMText个实例的DOM的一部分,例如。

<cellphones>\n\t<telefon>\n\t\t<model>Easy DB…
E           T   E        T     E      T      

其中E是DOMElement,T是DOMText

要解决这个问题,请按以下方式加载文档:

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

然后您的文档结构如下

<cellphones><telefon><model>Easy DB…
E           E        E      T

请注意,表示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中的所有telefon元素,并打印出节点名称,类型及其子节点的urlencoded节点值。保留空格时,您将获得类似

的内容
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个节点包含DOMDocument中的缩进和换行符。 %0A是一个换行符,而每个+都是一个空格。

当您将其与XML进行比较时,您会看到每个<telefon>元素之后有一个换行符后跟四个空格,直到<model>元素开始。同样,在结束<cena>和开始<telefon>之间只有一个换行符和两个空格。

这些节点的给定类型是3,其中 - according to the list of predefined constants - 是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个孩子的内容:

$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 DOM打印XML文件的内容

要最后回答您的问题,请查看第一个测试代码。你需要的一切都在那里。当然,到目前为止,你也得到了很好的其他答案。

答案 1 :(得分:2)

在我看来,你想要这样的东西:

<?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;
}

这可能不是您在格式化方面所需要的,但它应该向您显示您需要做的事情。

答案 2 :(得分:2)

这是经过试验和测试的解决方案。

<?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>';

  }


?>

答案 3 :(得分:2)

试一试

$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 />";
    }
}

答案 4 :(得分:0)

找到一种非常简单的方法:

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

或者您已将文档保存在变量中。

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

解决方案发现于: http://php.net/manual/fr/class.domelement.php