我如何使用php domdocument导入具有相同名称的xml列表

时间:2019-01-10 09:39:21

标签: php xml xml-parsing domdocument

使用php domdocument,导入xml文件,我无法获得“标签”列表

我尝试了多种方法,但我不能

xml文档:

<resource>
  <title>hello world</title>
  <tags>
    <resource>great</resource>
    <resource>fun</resource>
    <resource>omg</resource>
</resource>

php:

<?php
$url='test.xml';
$doc = new DOMDocument();
$doc->load($url);
$feed = $doc->getElementsByTagName("resource");
foreach($feed as $entry) {
echo $entry->getElementsByTagName("username")->item(0)->nodeValue;
echo '<br>';
echo $entry->getElementsByTagName("tags")->item(0)->nodeValue;
echo '<br>';
}

我希望支出是这样的列表:
你好,世界
很棒
好玩
omg

但是实际输出不是列表,结果是没有空格的句子: 你好世界greatfunomg

2 个答案:

答案 0 :(得分:2)

DOMDocument::getElementsByTagName()返回具有指定名称的所有后代元素节点。 DOMElement::$nodeValue将返回元素节点的文本内容,包括其所有后代。

在您的情况下,echo $entry->getElementsByTagName("tags")->item(0)->nodeValue获取所有tags,访问该列表的第一个节点并输出其文本内容。那就是greatfunomg

使用DOM方法访问节点非常冗长,并且需要大量代码,并且如果您想在很多情况下进行操作,也是如此。如果使用Xpath表达式,则容易得多。允许您标量值和来自DOM的节点列表。

$xml = <<<'XML'
<_>
    <resource>
      <title>hello world</title>
      <tags>
        <resource>great</resource>
        <resource>fun</resource>
        <resource>omg</resource>
      </tags>
    </resource>
</_>
XML;

$document = new DOMDocument();
$document->loadXML($xml);
// create an Xpath instance for the document
$xpath = new DOMXpath($document);

// fetch resource nodes that are a direct children of the document element
$entries = $xpath->evaluate('/*/resource');
foreach($entries as $entry) {
    // fetch the title node of the current entry as a string
    echo $xpath->evaluate('string(title)', $entry), "\n";

    // fetch resource nodes that are children of the tags node
    // and map them into an array of strings
    $tags = array_map(
      function(\DOMElement $node) {
          return $node->textContent;
      },
      iterator_to_array($xpath->evaluate('tags/resource', $entry))
    );

    echo implode(', ', $tags), "\n";
}

输出:

hello world 
great, fun, omg

答案 1 :(得分:0)

如果您只需要输出每个<resource>元素的第一条文本-不管它在哪里,则使用XPath并(确保在加载时忽略空白)选择该文本的第一个子元素并输出节点值。

忽略加载时的空白很重要,因为空白将为每个元素周围的所有填充创建节点,因此每个<resource>元素的第一个子元素可能只是换行或制表符。

$xml = '<root>
    <resource>
      <title>hello world</title>
      <tags>
        <resource>great</resource>
        <resource>fun</resource>
        <resource>omg</resource>
      </tags>
    </resource>
</root>';

$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->loadXML($xml);
// $doc->load($filename);   // If loading from a file
$xpath = new DOMXpath($doc);

$resources = $xpath->query("//resource");
foreach ( $resources as $resource ){
    echo $resource->firstChild->nodeValue.PHP_EOL;
}

其输出为

hello world
great
fun
omg

或者不使用XPath ...

$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->loadXML($xml);
//$doc->load($filename);

$resources = $doc->getElementsByTagName("resource");
foreach ( $resources as $resource ){
    echo $resource->firstChild->nodeValue.PHP_EOL;
}