Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP XML DOM解析混合内容_Php_Xml_Xpath_Domdocument - Fatal编程技术网

PHP XML DOM解析混合内容

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

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

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