2017-01-17 75 views
0

我有一個用XSD文件定義好的XML文檔。 XML文檔包含類似以下內容:PHP XML DOM解析混合內容

<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

我正在使用DOMdocument來查找節點: $ xml = new DOMDocument(); $ xml-> load(* XMLPATH *); $ node = $ xml-> getElementsByTagName(「element」) - > item(0) 然後以下所有內容都會忽略嵌套元素: $ node-> nodeValue $ node-> C14N(); 我也遵循這個指南無濟於事: http://stackoverflow.com/questions/2087103/how-to-get-innerhtml-of-domnode – user2502611

+0

@FelippeDuarte根據要求更新 – user2502611

回答

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。 作爲一個額外的問題,它會更快導航domdocument使用xpath而不是getelement方法,如果是的話,我很想改造其餘的網站。 – user2502611

+0

查詢應該圍繞bar而不是foo,I.E'// bar // text()| // //杆元件/ @ B」。對不起,如果這是不正確的,因爲我試圖拿起XPath – user2502611

+0

給定輸入片段,使用'//foo // text()| // foo // element/@ b'將在'bar'元素之前,之間和之後包含空白文本節點,我不知道你是否想要它們,如果你只使用'// bar // text )| // bar // element/@ b'結果只是'text 2和更多text_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; 
} 
+0

此解決方案是否將所有文本內容都包含在單個XML_TEXT_NODE中,或者嵌套元素是否將文本拆分爲2個XML_TEXT_NODE? – user2502611

+0

@ user2502611 XML DOM將您的示例中第一個元素的內容視爲由三個DOM節點組成:XML_TEXT_NODE(「text」),XML_ELEMENT_NODE(XML元素)和XML_TEXT_NODE(「以及更多文本」)。 – PowerGamer