XSLT:从一个上下文移动到for-each内的其他上下文节点

时间:2013-02-24 03:43:43

标签: xml xslt xslt-1.0 xslt-2.0

我正在编写一个XSL转换,我无法移动到root并访问其中的每个节点。

假设我在一个上下文中。我有一种情况,我必须去外部节点从那里获取一个值,并返回到相同的上下文。

这是我的XML文件。

    <xml version=1.0>

    <abc>
     <parts>
            <part pno="10506">
              <pname>Land Before Time I</pname>
              <qoh>200</qoh>
              <price>19.99</price>
              <level>20</level>
            </part>
            …
      </parts>
       <orders>
            <order ono="1022" takenBy="1001" customer="2222">
              <receivedDate>1995-02-13</receivedDate>
              <shippedDate>1995-02-20</shippedDate>
              <items>
                <item>
                  <partNumber>10601</partNumber>
                  <quantity>1</quantity>
                </item>
                <item>
                  <partNumber>10701</partNumber>
                  <quantity>1</quantity>
                </item>
              </items>
         </order>

     .....
     </orders>
    </abc>

我在xsl:for-each中的“item”标签内进行迭代,但我想进入“part”标签并获取一个值并返回相同的上下文。

更详细一点:我正在填写一张桌子。我的表有4列:

  • partname:我必须到<part>获取名称。 (这是我被困的地方)
  • 数量:这对我来说不是问题,因为它是<item>的子元素。
  • 价格:我遇到同样的问题。
  • 总计:很容易。

请帮我从零件标签中获取零件名称和价格的值。

以下代码对我不起作用。

  <?xml version="1.0" encoding="UTF-8"?>

    <xsl:stylesheet>

        <table>
             <xsl:param name="param1" />

             <xsl:variable name="temp" select ="name(/*)"/>
               <xsl:for-each select=".//order[@ono=$param1]/items/item">
                     <tr>
          <td> <xsl:value-of select="$temp//part[@pno=partNumber]/pname"/>  </td>
          <td> <xsl:value-of select="quantity"/> </td>                                                       
          <td> <xsl:value-of select="$temp//part[@pno=partNumber]/price"/>  </td>
          <td> <xsl:value-of select="quantity*$temp//part[@pno=partNumber]/price"/>  </td>
                </tr>
            </xsl:for-each>
           </table>      




    <xsl:stylesheet>

我尝试使用谷歌搜索,但我找不到解决问题的确切方法。我写的代码引发了一些错误。我尝试将“temp”的选择值更改为root(。),但它不起作用。

我只需要一个提示。我不需要答案。只是暗示对我来说已经足够了。

过去5个小时我遇到了这个问题。请回复并帮助我。

2 个答案:

答案 0 :(得分:1)

如果要在谓词中引用与当前上下文相关的内容,可以使用current()

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:param name="param1" select="1022" />

  <xsl:template match="/">
    <table>
      <xsl:for-each select="//order[@ono=$param1]/items/item">
        <tr>
          <td>
            <xsl:value-of select="//part[@pno=current()/partNumber]/pname"/>
          </td>
          <td>
            <xsl:value-of select="quantity"/>
          </td>
          <td>
            <xsl:value-of select="//part[@pno=current()/partNumber]/price"/>
          </td>
          <td>
            <xsl:value-of select="quantity * //part[@pno=current()/partNumber]/price"/>
          </td>
        </tr>
      </xsl:for-each>
    </table>
  </xsl:template>
</xsl:stylesheet>

然而,更有效的方法是使用密钥。我还清理了一下XSLT,以便更好地使用模板并避免在路径中重复:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:key name="kPart" match="part" use="@pno" />

  <xsl:param name="param1" select="1022" />

  <xsl:template match="/">
    <table>
      <xsl:apply-templates select="//order[@ono=$param1]/items/item" />
    </table>
  </xsl:template>

  <xsl:template match="item">
    <xsl:variable name="part" select="key('kPart', partNumber)" />
    <tr>
      <td>
        <xsl:value-of select="$part/pname"/>
      </td>
      <td>
        <xsl:value-of select="quantity"/>
      </td>
      <td>
        <xsl:value-of select="$part/price"/>
      </td>
      <td>
        <xsl:value-of select="quantity * $part/price"/>
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

Root不是.。 Root是/。如果您想要根元素名称为“part”的任何后代,请使用//part

如果您将<xsl:template match="/">放在<table>之前并将</xsl:template>放在</table>之后,那么当XML解析器解析文档根目录时,XSL处理器将生成您的表格元素。

您的xsl:stylesheet开放标记需要几个属性。对于XSLT 1.0,它应该是<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

我认为这些信息可能足以让你发挥作用。

如果您需要提高效率,则应避免使用//并使用xsl:key。您可以找到xsl:key in the XSL Transformations specification的定义,基础知识和简单示例。