dougan4663 2015-03-24 09:50 采纳率: 0%
浏览 47
已采纳

PHP xpath在foreach循环中按属性获取元素

im am trying to loop through all the LINE_ITEMS and it works fine but in the foreach-loop im trying to access the single LINE_ITEM by attribute by using xpath but i don't get any result. Does anyone know the problem ?

 foreach($items = $xmlData->xpath('//zw:LINE_ITEM') as $item) {
    $item->xpath('//namespace:PID[@type="erp_pid"]'); No result
}
$xmlData->xpath('//zw:LINE_ITEM') 

works fine i get all LINE_ITEMS but when i try to do some xpath on the item i don't get any result.

How can i access the PID value of for example "erp_pid" ?

<?xml version="1.0" encoding="UTF-8"?>
<NM_DOCS>
    <NM_DOC>
        <DOCUMENT qualifier="default" role="original" test="false" type="orders">
            <VERSION>4.0</VERSION>
            <HEADER>
                <CONTROL_INFO>
                    <LAST_SAVE_DATE>2015-03-18T13:44:32+01:00</LAST_SAVE_DATE>
                    <PROCESS_TYPE>silent</PROCESS_TYPE>
                    <SOURCE>sales</SOURCE>

                </CONTROL_INFO>
                <SOURCING_INFO>
                    <REFERENCES>
                        <REFERENCE type="order_nexmart">
                            <ID>109546063</ID>
                            <DATES>
                                <DATE type="order">2015-03-18T13:44:30+01:00</DATE>
                            </DATES>
                        </REFERENCE>
                    </REFERENCES>
                </SOURCING_INFO>
                <DOCUMENT_INFO>
                    <DOCUMENT_ID>Test bestellnummer</DOCUMENT_ID>
                    <DATES>
                        <DATE type="delivery_ordered">2015-04-19T12:41:41+02:00</DATE>
                    </DATES>
                    <PARTIES>
                        <PARTY type="buyer">
                            <BUSINESS_ROLE>commercial</BUSINESS_ROLE>
                            <PORTAL_ID>BDE600028</PORTAL_ID>
                            <ADDITIONAL_IDS>                             
                            </ADDITIONAL_IDS>
                            <ADDRESS>                                
                            </ADDRESS>
                            <CONTACT_DETAILS>                                
                                <ACCOUNTS>
                                    <ID type="emart">sales.nexmart</ID>
                                </ACCOUNTS>
                            </CONTACT_DETAILS>
                        </PARTY>
                        <PARTY type="supplier">
                            <BUSINESS_ROLE>commercial</BUSINESS_ROLE>
                            <PORTAL_ID>zweygart_app_de</PORTAL_ID>
                            <ADDITIONAL_IDS>

                            </ADDITIONAL_IDS>
                            <ADDRESS>

                            </ADDRESS>
                            <CONTACT_DETAILS>

                            </CONTACT_DETAILS>
                        </PARTY>
                        <PARTY type="delivery">
                            <BUSINESS_ROLE>commercial</BUSINESS_ROLE>
                            <ADDRESS>

                            </ADDRESS>
                            <CONTACT_DETAILS>

                            </CONTACT_DETAILS>
                        </PARTY>
                        <PARTY type="invoice_recipient">
                            <ADDRESS>

                            </ADDRESS>
                            <CONTACT_DETAILS>

                            </CONTACT_DETAILS>
                        </PARTY>
                    </PARTIES>                    
                    <REMARKS>
                        <REMARK type="order">Test bemerkung</REMARK>
                    </REMARKS>
                </DOCUMENT_INFO>
            </HEADER>
            <LINE_ITEMS>
                <LINE_ITEM>                    
                    <PRODUCT_ID>
                        <SUPPLIER_PID>119556</SUPPLIER_PID>
                        <GTIN>4030646269130</GTIN>
                        <ADDITIONAL_PIDS>
                            <PID type="supplier_pid_original">119556</PID>
                            <PID type="gtin_original">4030646269130</PID>
                            <PID type="erp_pid">119556</PID>
                        </ADDITIONAL_PIDS>
                        <DESCRIPTIONS>
                            <DESCR type="short">short desc</DESCR>
                            <DESCR type="short_original">some text</DESCR>
                        </DESCRIPTIONS>
                    </PRODUCT_ID>                    
                </LINE_ITEM>
                <LINE_ITEM>                    
                    <PRODUCT_ID>
                        <SUPPLIER_PID>123456789</SUPPLIER_PID>
                        <GTIN>123456789</GTIN>
                        <ADDITIONAL_PIDS>
                            <PID type="supplier_pid_original">123456</PID>
                            <PID type="gtin_original">123456</PID>
                            <PID type="erp_pid">123456</PID>
                        </ADDITIONAL_PIDS>
                        <DESCRIPTIONS>
                            <DESCR type="short">short desc</DESCR>
                            <DESCR type="short_original">Some description</DESCR>
                        </DESCRIPTIONS>
                    </PRODUCT_ID>                                       

                </LINE_ITEM>
            </LINE_ITEMS>

        </DOCUMENT>
    </NM_DOC>
</NM_DOCS>
  • 写回答

2条回答 默认 最新

  • duanou3868 2015-03-24 10:40
    关注

    The problem is not XPath but SimpleXML. SimpleXMLElement::xpath() is limited. It converts the result into an array of SimpleXMLElement objects, but here are other nodes in a DOM. More important you will have to register the namespaces on each new SimpleXMLElement again.

    $element = new SimpleXMLElement($xml);
    $element->registerXPathNamespace('namespace', 'urn:foo');
    
    foreach($element->xpath('//namespace:LINE_ITEMS/namespace:LINE_ITEM') as $item) {
      $item->registerXPathNamespace('namespace', 'urn:foo');
      var_dump((string)$item->xpath('.//namespace:PID[@type="erp_pid"]')[0]);
    }
    

    Output:

    string(6) "119556"
    string(6) "123456"
    

    You might notice that I prefixed your detail expression with an .. A slash at the start of the expression always makes it relative to the document itself, not the current node. The . represents the current node.

    If you use DOM directly, you create a separate DOMXPath object and register the namespaces on this object. Additionally you can use XPath expressions that return scalar values.

    $dom = new DOMDocument();
    $dom->loadXml($xml);
    $xpath = new DOMXPath($dom);
    $xpath->registerNamespace('namespace', 'urn:foo');
    foreach($xpath->evaluate('//namespace:LINE_ITEMS/namespace:LINE_ITEM') as $node) {
      var_dump($xpath->evaluate('string(.//namespace:PID[@type="erp_pid"])', $node));
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 C#调用python代码(python带有库)
  • ¥15 矩阵加法的规则是两个矩阵中对应位置的数的绝对值进行加和
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)
  • ¥20 怎么在stm32门禁成品上增加查询记录功能
  • ¥15 Source insight编写代码后使用CCS5.2版本import之后,代码跳到注释行里面