首页 文章

PHP XML DOM解析混合内容

提问于
浏览
0

我有一个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

    您可以使用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;
    

    结果是

    text 2 and some more text
       Just text
    
  • 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;
    }
    

相关问题