我正在尝试创建和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>
答案 0 :(得分:2)
Call-Name
元素位于名称空间中,其URI为“http://www.mysite.com/interface/genericnamespace”。因此你需要
使用该命名空间按名称选择,或
使用名称空间无关的方法 访问它。
元素与“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]/...