PHP XML DOM 正在解析混合内容
PHP XML DOM parseing mixed content
我有一个 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?
感谢您的帮助。
您可以将 XPath 用于 select text()
节点,将 @b
用于 select 属性,联合运算符 |
将全部放入正确顺序:
$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
以下代码应该让您了解如何在不使用 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;
}
我有一个 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?
感谢您的帮助。
您可以将 XPath 用于 select text()
节点,将 @b
用于 select 属性,联合运算符 |
将全部放入正确顺序:
$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
以下代码应该让您了解如何在不使用 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;
}