从具有与根不同的命名空间的另一个元素中检索元素

时间:2011-04-29 20:45:44

标签: xml xpath

我正在尝试创建和xpath表达式,它返回一个节点的值但是我发现我自己无法这样做,因为该元素位于另一个具有与根不同的命名空间的元素中。

例如,我正在尝试从以下xml中检索 InternalSystemId ,但传统的XML无法正常工作

XPATH我正在尝试使用

/SomeMessage[1]
   /MessageDetails[1]
      /PAYLOAD[1]
         /Call-Name[1]
            /Body[1]
               /ActionToTake[1]
                  /Fields[1]
                     /InternalSystemId[1]

XML我有

<?xml version="1.0" encoding="UTF-8"?>
<SomeMessage>
    <MessageDetails>
        <FROM/>
        <TO/>
        <PAYLOAD>
            <Call-Name 
            xmlns:ns0="http://www.mysite.com/interface/genericnamespace"
            xmlns="http://www.mysite.com/interface/genericnamespace">
                <Header xmlns="">
                    <Transaction>
                        <Mandatory>
                            <TransactionId>111111</TransactionId>
                        </Mandatory>
                        <System-Use-Only>
                            <Name>Receiver</Name>
                            <Someone>Customer</Someone>
                            <Something>OUT</Something>
                        </System-Use-Only>
                    </Transaction>
                </Header>
                <Body xmlns="">
                    <ActionToTake>
                        <TransactionName>ActionToTake</TransactionName>
                        <Fields>
                            <InterfaceId>w00tie</InterfaceId>
                            <CustomerSystemId>555555</CustomerSystemId>
                            <InternalSystemId>4444444</InternalSystemId>
                            <SubmittedDate
                            >2011-04-14T12:00:00-00:00</SubmittedDate>
                            <EventType>A type</EventType>
                        </Fields>
                    </ActionToTake>
                </Body>
            </Call-Name>
        </PAYLOAD>
    </MessageDetails>
</SomeMessage>

1 个答案:

答案 0 :(得分:2)

Call-Name元素位于名称空间中,其URI为“http://www.mysite.com/interface/genericnamespace”。因此你需要

  1. 使用该命名空间按名称选择,或

  2. 使用名称空间无关的方法 访问它。

  3. 元素与“root”(元素)位于不同名称空间的事实并不直接相关。

    要做#1,你必须在XPath执行环境中声明命名空间的前缀;例如在XSLT样式表中,您可以放置​​xmnls:mysite="http://www.mysite.com/interface/genericnamespace"。然后,您将使用该前缀和元素名称选择元素,例如

    /SomeMessage[1]/MessageDetails[1]/PAYLOAD[1]/mysite:Call-Name[1]/Body[1]/ActionToTake[1]/Fields[1]/InternalSystemId[1]
    

    当然你可以使用你喜欢的任何前缀。

    要做#2,有几个选项。如果Call-Name元素没有兄弟姐妹,或者,在其兄弟姐妹之间的一个稳定的秩序,你可以代替*它的名字。这样,XPath将选择PAYLOAD[1]的任何元素子元素,无论其名称或命名空间如何:

    /SomeMessage[1]/MessageDetails[1]/PAYLOAD[1]/*[1]/...
    

    另一种选择,如果你是勇敢和自信的输入XML的结构,是使用//跳过该元素:

    /SomeMessage[1]/MessageDetails[1]/PAYLOAD[1]//Body[1]/...
    

    如果您仍然需要按名称进行测试,而不是按名称空间进行测试,则可以使用local-name() =

    /SomeMessage[1]/MessageDetails[1]/PAYLOAD[1]/*[local-name()='Call-Name']/Body[1]/...