我有以下xml片段,我需要在xsl:
中使用xpath表达式从中提取值<?xml version="1.0" encoding="UTF-8"?>
<ns0:NotificationRequest xmlns:ns0="http://www.somedomain.com/schemas/message/Request">
<ns1:Header xmlns:ns1="http://www.somedomain.com/schemas/common/Header">
<ns1:Element1>Element 1 Value</ns1:Element1>
<ns1:Element2>Element 2 Value</ns1:Element2>
</ns1:Header>
<ns0:MessageValues>
<ns0:MessageValue>
<ns0:Name>Name1</ns0:Name>
<ns0:Value>Value1</ns0:Value>
</ns0:MessageValue>
<ns0:MessageValue>
<ns0:Name>Name2</ns0:Name>
<ns0:Value>Value2</ns0:Value>
</ns0:MessageValue>
</ns0:MessageValues>
</ns0:NotificationRequest>
要检索Element1或Element2的值而不考虑名称空间,我知道我可以使用xsl/xpath表达式,如下所示:
<xsl:value-of select="//*[local-name()='Element1']" />
但是,我正在努力使用xpath表达式来检索名称/值对部分中的ns0: value节点的值。例如,无论名称空间如何,获得"Value1"或"Value2"的表达式是什么样子的?我知道如何使用名称空间,但我不能使用该方法,因为我需要处理的xml文件在同一文档中重用了名称空间。
"对于命名空间,它看起来像这样:
<xsl:value-of select="//*[ns0:Name = 'Name1']/ns0:Value"/>
"
您可以使用and
运算符来检查元素的local-name
和值。此外,Value
不是Name
的子结点,而是following-sibling
:
//*[local-name()='Name' and .='Name1']/following-sibling::*[local-name()='Value']
如果名称空间确实不携带任何信息,只会造成阻碍,那么最好的方法是在预处理过程中删除它们,而不是以这种方式将所有XPath表达式弄得乱七八糟。
<xsl:template match="*" mode="get-rid-of-namespaces">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates mode="#current"/>
</xsl:element>
</xsl:template>
Har07的答案很酷,但我一直用相反的方法来做。我选择我想要的节点,然后用兄弟节点限定它(也要专门命名我的兄弟节点,而不是依赖于它是下一个节点):
//*[local-name()='Value'][../*[local-name()='Name' and .='Name1']]
伟大的测试工具与你的场景和我的答案:http://www.xpathtester.com/xpath/38270fcac4d94d3d59b47069301f4456
我们在EDI中使用REF段做了很多这样的事情,例如:
<ns0:X12_00401_850 xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006">
<ns0:REF>
<REF01>IA</REF01>
<REF02>Name1</REF02>
</ns0:REF>
<ns0:REF>
<REF01>VN</REF01>
<REF02>Name1</REF02>
</ns0:REF>
</ns0:X12_00401_850>
你基本上想要查找REF02的VN为例…
//*[local-name()='REF']//*[local-name()='REF02'][..//*[local-name()='REF01' and text()='VN']]
我想通过添加第二个例子,它将帮助人们做BizTalk和EDI找到相同的问题/答案。