开发者

Retrieving an element from within another element with a different namespace than the root

I'm trying to create and xpath expression that returns me the value of a node however I found my self unable to do so as the element is within another element that has a different namespace from the root.

For example I'm trying to retrieve the InternalSystemId from the following xml but traditional XML won't work

XPATH I'm trying to use

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

XML I'm have

<?xml version="1.0" encoding="UTF-8"?>
<SomeMessage>
    <MessageDetails>
        <FROM/>
        <TO/&开发者_开发问答gt;
        <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>


The Call-Name element is in the namespace whose URI is "http://www.mysite.com/interface/genericnamespace". Therefore you need to either

  1. select it by name using that namespace, or

  2. use a namespace-agnostic method to access it.

The fact that the element is in a different namespace from the "root" (element) is not directly relevant.

To do #1, you have to declare a prefix for the namespace in your XPath execution environment; e.g. in an XSLT stylesheet you could put xmnls:mysite="http://www.mysite.com/interface/genericnamespace". Then you would select the element using that prefix and the element name, e.g.

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

Of course you could use whatever prefix you like.

To do #2, there are several options. If the Call-Name element has no siblings, or comes in a stable order among its siblings, you could substitute * for its name. That way, the XPath will select any element child of PAYLOAD[1], regardless of its name or namespace:

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

Another option, if you're brave and confident about the structure of your input XML, is to use // to skip over that element:

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

If you still need to test by name, but not by namespace, you can use local-name() =:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜