PHP XML DOM解析混合内容

时间:2017-01-17 17:57:11

标签: php xml xpath domdocument

我有一个XML文档,它使用XSD文件定义良好。 xml文档包含类似于以下内容:

<foo>
   <bar>text <element a="1" b="2" c="3" /> and some more text</bar>
   <bar>Just text</bar>
</foo>

我想用PHP来解析它,只是将其中一个属性值(将在代码中的其他地方决定)与其余文本内联,这个例子我想要“B”和输出应该是:

"text 2 and some more text"
"Just text"

我遇到以这种格式获取输出的问题,因为我找不到分割节点文本的方法,以便我可以插入属性值或输出节点的纯xml。

我的偏好是使用PHP的DOMDocument方法来做到这一点。虽然我没有学习XPath,但我愿意学习它,如果它能使这项任务成为可能。我还会考虑更改嵌套节点的格式,尽管这是最后的手段。

我正在使用DOMdocument来查找节点:

$xml= new DOMDocument();
$xml->load(XMLPATH); 
$node = $xml->getElementsByTagName("element")->item(0);

然后以下所有内容都忽略了嵌套元素:

$node->nodeValue;
$node->C14N(); 

我也遵循本指南无济于事: How to get innerHTML of DOMNode?

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

您可以使用XPath选择text()节点和@b来选择属性,而union运算符|将以正确的顺序显示所有节点:

$xml = <<<EOD
<foo>
   <bar>text <element a="1" b="2" c="3" /> and some more text</bar>
   <bar>Just text</bar>
</foo>
EOD;

$doc = new DOMDocument();
$doc->loadXML($xml);

$xpath = new DOMXPath($doc);
$nodeList = $xpath->query('//foo//text() | //foo//element/@b', $doc);

$result = '';

for ($i = 0; $i < $nodeList->length; $i++) {
    $result .= $nodeList[$i]->textContent;
}
echo $result;

结果是

   text 2 and some more text
   Just text

答案 1 :(得分:0)

以下代码应该让您了解如何在不使用XPath的情况下实现目标:

<?php
$xml = '<foo>
    <bar>text <element a="1" b="2" c="3" /> and some more text</bar>
    <bar>Just text</bar>
</foo>'; // Your example XML.

$attr = 'b'; // Attribute of <element> you are interested in.

$doc = new DOMDocument();
$doc->loadXml($xml);

foreach($doc->documentElement->getElementsByTagName('bar') as $bar)
{
    $text = '';
    foreach($bar->childNodes as $child)
    {
        switch($child->nodeType)
        {
        case XML_ELEMENT_NODE:
            if($child->nodeName == 'element')
                $text .= $child->getAttribute($attr);
            break;
        case XML_TEXT_NODE:
            $text .= $child->textContent;
            break;
        }
    }
    echo $text . PHP_EOL;
}