2

我意识到这段代码不是最干净的,但不幸的是,正确地重构它不是一种选择。

问题是我希望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()没有正确选择节点?

4

1 回答 1

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>
于 2013-02-21T04:11:34.003 回答