PHP使用get值解析xml问题

时间:2014-07-24 06:07:45

标签: php xml parsing xpath

我收到文件为xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Document xmlns="http://adress1" xmlns:adr="http://adress2" xmlns:inst="adress3" xmlns:meta="adress4" xmlns:oso="adress5" xmlns:str="adress6" xmlns:xsi="adress7">
    <str:DataDocument>
        <str:Head/>
        <meta:Date typeDate="created">
             <meta:Time>2014-07-23T12:35:20+02:00</meta:Time>
        </meta:Date>
    </str:DataDocument>
    <contentDocument format="text/xml" coding="xml">
        <Values>
            <Attachments>
                  <str:Attachment format="text/html" code="base64" nameFile="name.html">
                       <str:DataAttachment>VALUESRECEIVE</str:DataAttachment>
                   </str:Attachment>
                   <str:Attachment format="text/xml" code="base64" nameFile="name.xml">
                       <str:DataAttachment>VALUESToRECEIVE</str:DataAttachment>
                   </str:Attachment>
                   <str:Attachment format="text/xml" code="base64" nameFile="name2.xml">
                       <str:DataAttachment>VALUESToRECEIVE</str:DataAttachment>
                   </str:Attachment>
             </Attachments>
         </Values>
    </contentDocument>
    (...)
</Document>

我必须为每个<str:DataAttachment>接收所有节点:<str:DataAttachment><str:Attachment>

我写了这个:

$attachment = new SimpleXMLElement(file_get_contents($file1));
//first way
$res = $attachment->xpath('contentDocument/Values/Attachments/*');
//second way            
$zalacznikiListFromXml = $attachment->contentDocument->Values->Attachments;
foreach ($attachmentListFromXml as $Attachments){
    foreach($Attachmentsas $strAttachment)
        $attachToDecode = $strAttachment['str:DataAttachment'];
}

xpath$attachment->contentDocument->Values->Attachments都返回空对象。

我不知道什么是问题。你能帮助我找到每一个str:DataAttachment吗?

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

阐述@Ghost的答案......

有几个原因导致你的第一种方式&#34;没有工作。

  1. 输入XML中的大多数元素都在默认命名空间中,即URI为"http://adress1"的命名空间。这是因为最外层元素具有默认的名称空间声明xmlns="http://adress1"。因此,所有不具有显式名称空间前缀的元素都会继承此默认名称空间。因此,为了在XPath中选择这些元素,您必须告诉XPath您希望URI为"http://adress1"的命名空间中的元素。 Ghost展示了如何声明名称空间前缀并在XPath中使用它。对于adress1命名空间,您可以使用$attachment->registerXPathNamespace('ns1', 'http://adress1');

  2. 其次,$attachment->xpath('contentDocument/...')与输入文档的结构不匹配。 $attachment保存输入文档的根节点,该节点是<Document>的不可见父节点。然后,您尝试选择名为contentDocument的根节点的子节点。但是<contentDocument><Document>的子节点,而不是根节点的子节点。所以你需要像$attachment->xpath('/*/ns1:contentDocument/ns1:Values/ns1:Attachments/*');

  3. 这样的东西

答案 1 :(得分:2)

如果您选择使用xpath,请首先使用注册命名空间。使用registerXPathNamespace

示例:

$attachToDecode = array();
$attachment = new SimpleXMLElement(file_get_contents($file1));
$attachment->registerXPathNamespace('str', 'adress6');
foreach($attachment->xpath('//str:DataAttachment') as $strAttachment) {
    $attachToDecode[] = (string) $strAttachment;
}

echo '<pre>';
print_r($attachToDecode);

示例输出:

VALUESRECEIVE
VALUESToRECEIVE
VALUESToRECEIVE