PHP XML DOM解析混合内容
我有一个用XSD文件定义良好的XML文档。xml文档包含与以下内容类似的内容:PHP XML DOM解析混合内容,php,xml,xpath,domdocument,Php,Xml,Xpath,Domdocument,我有一个用XSD文件定义良好的XML文档。xml文档包含与以下内容类似的内容: <foo> <bar>text <element a="1" b="2" c="3" /> and some more text</bar> <bar>Just text</bar> </foo> 我在获取这种格式的输出时遇到了一个问题,因为我无法找到分割节点文本的方法,以便插入属性值或输出节点的纯xml 我倾向于使用P
<foo>
<bar>text <element a="1" b="2" c="3" /> and some more text</bar>
<bar>Just text</bar>
</foo>
我在获取这种格式的输出时遇到了一个问题,因为我无法找到分割节点文本的方法,以便插入属性值或输出节点的纯xml
我倾向于使用PHP的DOMDocument方法来实现这一点。虽然我还没有学会XPath,但如果它能使这项任务成为可能,我愿意学习它。我也会考虑改变嵌套节点的格式,尽管这将是最后的选择。
我正在使用DOMdocument查找节点:
$xml= new DOMDocument();
$xml->load(XMLPATH);
$node = $xml->getElementsByTagName("element")->item(0);
然后,以下所有操作将忽略嵌套元素:
$node->nodeValue;
$node->C14N();
我也遵循了这一指南,但无济于事:
感谢您的帮助。您可以使用XPath选择
text()
节点和@b
选择属性,联合运算符|
将按正确顺序显示所有内容:
$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;
以下代码应该让您了解如何在不使用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;
}
loadXml($xml);
foreach($doc->documentElement->getElementsByTagName('bar')作为$bar)
{
$text='';
foreach($bar->childNodes作为$child)
{
开关($child->nodeType)
{
案例XML_元素_节点:
如果($child->nodeName=='element')
$text.=$child->getAttribute($attr);
打破
案例XML_文本_节点:
$text.=$child->textContent;
打破
}
}
echo$text.PHP\u EOL;
}
到目前为止您做了什么?给我们看看代码!我正在使用DOMdocument查找节点:$xml=newdomdocument()$xml->load(XMLPATH)$node=$xml->getElementsByTagName(“元素”)->item(0),然后以下所有操作都忽略嵌套元素:$node->nodeValue$node->C14N();我也遵循了这一指南,但毫无用处:@FelippeDuarte根据请求进行了更新此解决方案是将所有文本内容都放在一个XML_text_节点中,还是嵌套元素将文本拆分为两个XML_text_节点?@user2502611 XML DOM将示例中第一个元素的内容视为由三个DOM节点组成:XML_text_节点(“text”),XML元素节点(XML元素)和XML文本节点(“还有更多的文本”)。哇,这么简单的解决方案,我想我现在必须学习Xpath了。另外一个问题是,使用xpath而不是getelement方法浏览domdocument会更快吗?如果是这样,我很想修改站点的其余部分。查询是否应该围绕bar而不是foo,即“//bar//text()|//bar//element/@b”。抱歉,如果这是错误的,因为我正在尝试拾取XPath给定输入片段,使用//foo//text()|//foo//element/@b
将包括bar
元素之前、之间和之后的空白文本节点,如果仅使用//bar//text(),我不知道您是否需要这些节点|//bar//element/@b
结果只有文本2和更多的文本just text
。啊,谢谢你这么说,我忘了foo节点将包含文本。我正在将它们处理成一个列表,因此我将使用//foo方法来避免使用普通节点。
text 2 and some more text
Just text
<?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;
}