我遇到了一个奇怪的问题,让我把头发撕掉了。我正在尝试在样式表中匹配XPath。它在我对匹配值进行硬编码时起作用,但在我尝试从变量中获取时却不行。我在这里做错了什么?
XML输入(显然非常简化):
<container>
<items>
<item>
<LocationID>LOCATION_4</LocationID>
</item>
<item>
<LocationID>LOCATION_4</LocationID>
</item>
</items>
</container>
XSLT模板($ DistinctLocations和$ dataNode是先前声明的变量,我的前几个打印输出是为了验证它们都在范围内)
<xsl:template name="LocationTemplate">
<xsl:for-each select="$DistinctLocations/Location">
<MY-CURRITEM>
<val>
<xsl:copy-of select="." />
</val>
<distinct>
<xsl:copy-of select="$DistinctLocations" />
</distinct>
<node>
<xsl:copy-of select="$dataNode" />
</node>
<itemloc>
<xsl:copy-of select="$dataNode//item[LocationID = 'LOCATION_4'][1]/LocationID" />
</itemloc>
<itemlocdot>
<xsl:copy-of select="$dctNode//risk[LocationID = .][1]/LocationID" />
</itemlocdot>
<itemloctext>
<xsl:copy-of select="$dctNode//risk[LocationID = text()][1]/LocationID" />
</itemloctext>
<itemloc2>
<xsl:copy-of select="$dataNode//item[string(LocationID) = string(.) ][1]/LocationID" />
</itemloc2>
<itemloc3>
<xsl:copy-of select="$dataNode//item[string(LocationID) = string(text()) ][1]/LocationID" />
</itemloc3>
</MY-CURRITEM>
</xsl:for-each>
</xsl:template>
输出:
<MY-CURRITEM>
<val>
<Location>LOCATION_4</Location>
</val>
<distinct>
<DistinctLocations>
<Location>LOCATION_4</Location>
</DistinctLocations>
</distinct>
<node>
<container>
<items>
<item>
<LocationID>LOCATION_4</LocationID>
</item>
<item>
<LocationID>LOCATION_4</LocationID>
</item>
</items>
</container>
</node>
<itemloc>
<LocationID>LOCATION_4</LocationID>
</itemloc>
<itemlocdot />
<itemloctext />
<itemloc2 />
<itemloc3 />
</MY-CURRITEM>
如您所见,我对该值进行硬编码的节点返回匹配项。我尝试匹配变量值的所有其他函数都无法匹配。由于硬编码有效,我猜测它是类型之间的某种不匹配,但我已经尝试了所有可以想到的类型转换组合,而且我没有得到任何结果。
编辑:人们正在请求整个样式表。这是巨大的,需要一些时间来简化。与此同时,这里是变量的来源:
$ DistinctLocations是从C#传递的参数
args.AddParam("DistinctLocations", string.Empty, xDistinctLocs.CreateNavigator().Select("/"));
和
<xsl:param name="DistinctLocations" />
$ dataNode是正在转换的原始XML,存储在变量中:
<xsl:variable name="dataNode" select="." />
答案 0 :(得分:1)
请注意以下简化示例:
<强> XML 强>
<root>
<locations>
<location>LOCATION_2</location>
</locations>
<items>
<item>
<id>1</id>
<location>LOCATION_1</location>
</item>
<item>
<id>2</id>
<location>LOCATION_2</location>
</item>
</items>
</root>
<强> XSLT 强>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/root">
<xsl:copy>
<xsl:for-each select="locations/location">
<location>
<value>
<xsl:value-of select="." />
</value>
<hard-code>
<xsl:copy-of select="//item[location='LOCATION_2']" />
</hard-code>
<dot>
<xsl:copy-of select="//items/item[location=.]" />
</dot>
<current>
<xsl:copy-of select="//items/item[location=current()]" />
</current>
</location>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<强>结果强>
<?xml version="1.0" encoding="utf-8"?>
<root>
<location>
<value>LOCATION_2</value>
<hard-code>
<item>
<id>2</id>
<location>LOCATION_2</location>
</item>
</hard-code>
<dot/>
<current>
<item>
<id>2</id>
<location>LOCATION_2</location>
</item>
</current>
</location>
</root>
为什么结果的<dot>
元素为空?因为在表达式中:
"//items/item[location=.]"
内部点表示外部item
节点 - 而不是当前location
节点。表达式正在查找item
,其值等于其location
子项的值。当然,不存在这样的项目。
这就是为什么XSLT添加了current() function,它在谓词中使用时不会改变上下文。