我意识到这段代码并不是最干净的,但不幸的是,正确地重构它不是一种选择。
问题是我希望第二次迭代的position()
返回一个真值。但是当使用position()
时,它永远不会返回true,正如第二次迭代所期望的那样。
但是如果我对选择值进行硬编码,它会返回预期的结果。这是一个例子:
<root>
<MainProducts>
<MainProduct>
<Published>0</Published>
</MainProduct>
<MainProduct>
<Published>1</Published>
</MainProduct>
</MainProducts>
<SubProducts>
<SubProduct>
<IsDefault>1</IsDefault>
</SubProduct>
<SubProduct>
<IsDefault>0</IsDefault>
</SubProduct>
</SubProducts>
</root>
XML内容:
<xsl:for-each select="/root/SubProducts/SubProduct">
<script type="text/javascript">
// Always returns false
console.log("Dynamic position " + <xsl:value-of select="position()" /> + " IsDefault: " + ( <xsl:value-of select="/root/MainProducts/MainProduct[position()]/Published" /> == 1 ? "true" : "false" ));
</script>
</xsl:for-each>
<script type="text/javascript">
// Returns false, but expected to return true on second iteration.
console.log("Hard coded position 1 IsDefault: " + ( <xsl:value-of select="/root/MainProducts/MainProduct[1]/Published" /> == 1 ? "true" : "false" ));
// Returns true
console.log("Hard coded position 2 IsDefault: " + ( <xsl:value-of select="/root/MainProducts/MainProduct[2]/Published" /> == 1 ? "true" : "false" ));
</script>
这是确切的控制台输出:
Dynamic position 1 IsDefault: false
Dynamic position 2 IsDefault: false
Hard coded position 1 IsDefault: false
Hard coded position 2 IsDefault: true
我在这里遗漏的是position()
没有正确选择节点?
答案 0 :(得分:5)
<script type="text/javascript">
// Always returns false
console.log("Dynamic position " +
<xsl:value-of select="position()" /> +
" IsDefault: " +
( <xsl:value-of select="/root/MainProducts/MainProduct[position()]/Published" />
== 1 ? "true" : "false" ));
</script>
在上面的代码中MainProduct[position()]
相当于MainProduct[true()]
),不要忘记position()
是上下文相关的!
所以,你实际上正在评估:
<xsl:value-of select="/root/MainProducts/MainProduct/Published" />
并且它总是输出由XPath表达式选择的第一个Published
元素的字符串值 - 恰好是0
。
更正代码:
<xsl:variable name="vPos" select="position()"/>
<script type="text/javascript">
// Always returns false
console.log("Dynamic position " +
<xsl:value-of select="position()" /> +
" IsDefault: " +
( <xsl:value-of select=
"/root/MainProducts/MainProduct[position()=$vPos]/Published" />
== 1 ? "true" : "false" ));
</script>
这是一个完整的转型:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:for-each select="/*/SubProducts/SubProduct">
<xsl:variable name="vPos" select="position()"/>
<script type="text/javascript">
console.log("Dynamic position " +
<xsl:value-of select="position()" /> +
" IsDefault: " +
( <xsl:value-of select=
"/*/MainProducts/MainProduct
[position()=$vPos]/Published" />
== 1 ? "true" : "false" ));
</script>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<root>
<MainProducts>
<MainProduct>
<Published>0</Published>
</MainProduct>
<MainProduct>
<Published>1</Published>
</MainProduct>
</MainProducts>
<SubProducts>
<SubProduct>
<IsDefault>1</IsDefault>
</SubProduct>
<SubProduct>
<IsDefault>0</IsDefault>
</SubProduct>
</SubProducts>
</root>
产生了想要的正确结果:
<script type="text/javascript">
console.log("Dynamic position " +
1 +
" IsDefault: " +
( 0
== 1 ? "true" : "false" ));
</script>
<script type="text/javascript">
console.log("Dynamic position " +
2 +
" IsDefault: " +
( 1
== 1 ? "true" : "false" ));
</script>