要求是在HL1Loop中找到具有HL03 ='P'和HL01 ='3'的MAN02段的值(在可能具有几十个HL1Loops的文件中,但为了再现该目的,我仅包括一对)题。)
我有这么多工作:
//*[local-name()='HLLoop1'][.//*[HL03='P'] and .//*[HL01='3']]
将返回所需的HLLoop1(下面有示例数据)。我有理由获得该特定项目,这里解释得太冗长(解析代表856 EDI预先发货通知文档的Microsoft BizTalk架构)。可能还有其他HLLoop1也有“MAN02”,这就是我需要的。
现在我想只返回MAN02值。试过这个,但这是不行的:
//*[local-name()='HLLoop1']//MAN/MAN02[.//*[HL03='P'] and .//*[HL01='3']]
我是否需要添加更多前缀才能让HL03返回几个节点,这样的话?
//*[local-name()='HLLoop1']//MAN/MAN02[.//.//.//*[HL03='P'] and .//.//.//*[HL01='3']]
或者我会在最后添加一些东西:
//*[local-name()='HLLoop1'][.//*[HL03='P'] and .//*[HL01='3']]//*MAN02
这给了“额外的非法令牌”,我认为可能在正确的位置添加更多括号将解决它。
我知道这是让轴和“where子句”笔直的问题。
示例:http://www.xpathtester.com/xpath/3005df62b369fd0fff86e7b3e492a377
数据
<ns0:X12_00401_856 xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006">
<ns0:HLLoop1>
<ns0:HL>
<HL01>2</HL01>
<HL02>1</HL02>
<HL03>O</HL03>
</ns0:HL>
<ns0:PRF>
<PRF01>287775</PRF01>
</ns0:PRF>
</ns0:HLLoop1>
<ns0:HLLoop1>
<ns0:HL>
<HL01>3</HL01>
<HL02>2</HL02>
<HL03>P</HL03>
</ns0:HL>
<ns0:MAN>
<MAN01>CP</MAN01>
<MAN02>465467995515</MAN02>
</ns0:MAN>
</ns0:HLLoop1>
</ns0:X12_00401_856>
我将使用它XSLT,如下所示:
<LineItemCarrierTrackingNum>
<xsl:variable name="currentHL02" select="HL02" />
<xsl:value-of select="concat("//*[local-name()='HLLoop1'][.//*[HL03='O'] and ..//*[HL01='", $currentHL02,"']]//*MAN02"; />
</LineItemCarrierTrackingNum>
我希望我可以将XPath构建为变量,如上所示......
如果你正在使用XSLT(即使没有),你应该避免使用/*[local-name()='..']
,它可以选择比你想要的更多(更不用说是不可读的)。另请注意,使用显式路径比后代轴更有效。
考虑以下样式表:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://schemas.microsoft.com/BizTalk/EDI/X12/2006"
exclude-result-prefixes="ns0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/ns0:X12_00401_856">
<result>
<xsl:value-of select="ns0:HLLoop1[ns0:HL/HL01='3' and ns0:HL/HL03='P']/ns0:MAN/MAN02"/>
</result>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<result>465467995515</result>
你的问题的简单答案是使用表达式//MAN02
。
好的,这可能不是你想要的答案;但如果是这样的话,那是因为你没有解释真正的问题。
从单个输入文档中使用XPath获取数据通常是微不足道的;当您想构建一个也可以与其他文档一起使用的表达式时(即,文档在某些方面与初始测试用例不同),就会出现问题。因此,您需要解释不变量的含义:样本文档的哪些部分是一般类文档的可靠特征,哪些部分是偶然的?如果您的所有文档都包含一个MAN02元素,就像示例文档那样,那么检索MAN02元素就很容易了。
好吧,我想我明白了,但想知道是否有更好的方法。
//*[local-name()='HLLoop1'][//*[HL03='P'] and //*[HL01='3']]//MAN02
这是我在原始问题中的选项之一,但需要// MAN02而不是// * MAN02。另一种方式也是如此,但同意评论它过于迟钝:
//*[local-name()='HLLoop1']//MAN02[..//..//*[HL03='P'] and ..//..//*[HL01='3']]
有时,你必须休息一晚,并对问题有一个新的看法。我之前尝试的问题:
1)MAN有一个命名空间,所以只是跳过// MAN02
2)我使用.//而不是..//(一个点是自己,两个点是父母)。因为我找到了MAN02,所以我必须找两个父母(一个家长带mae回到MAN,另一个家长带我回HLLOOP1)。
现在我需要在XSLT中尝试变量,看看它是否可以在那里工作。