XML / XSLT:在XSLT中从XML中的两个不同节点提取信息?

时间:2012-08-02 20:36:08

标签: xml xslt

所以我有这段代码:

<xsl:for-each select="item">
<Row>
    <Cell Borders="#ffffff">
      <xsl:attribute name="Background">
        <xsl:choose>
          <xsl:when test="position() mod 2 = 1">#CCCCFF</xsl:when>
          <xsl:when test="position() mod 2 = 0">#FFFFFF</xsl:when>
        </xsl:choose>
      </xsl:attribute>
      <Paddings Left="5" Right="5" Top="2" Bottom="2"/>
      <xsl:for-each select="//queries/query/selection/dataItem">
      <Text Style="TableContent">                                               
        <xsl:value-of select="@name"/>                                                                                        
      </Text>
      </xsl:for-each>   
    </Cell>
    <Cell Borders="#ffffff">
      <xsl:attribute name="Background">
        <xsl:choose>
          <xsl:when test="position() mod 2 = 1">#CCCCFF</xsl:when>
          <xsl:when test="position() mod 2 = 0">#FFFFFF</xsl:when>
        </xsl:choose>
      </xsl:attribute>
      <Paddings Left="5" Right="5" Top="2" Bottom="2"/>
      <Text Style="TableContent">
      <xsl:choose>
      <xsl:when test="qi">
        <xsl:value-of select="qi"/>
      </xsl:when>
      <xsl:otherwise>
        <Text>N/A</Text>
      </xsl:otherwise>
      </xsl:choose> 
      </Text>
    </Cell>
</Row>
</xsl:for-each>

我试图从XML中提取信息,但是信息在两个不同的节点中,有两个不同的XPATH。我还需要匹配一个节点的信息,即名称。到另一个位于不同位置的节点,使用不同的XPATH。有没有办法遍历节点中的每个名称,并将其与同一XML中的另一个节点中的信息相匹配?

EDIT Added link to original XML

非常感谢

1 个答案:

答案 0 :(得分:1)

您似乎正在尝试访问 dataItem 元素,其中表达式元素与当前项目的 name 元素匹配。

在这种情况下,您可以创建一个键,用表达式

来查找 dataItem 记录
<xsl:key name="dataItems" match="dataItem" use="expression" />

然后,不要像你当前那样循环遍历所有 dataItem 记录......

<xsl:for-each select="//queries/query/selection/dataItem"> 

您可以将此行替换为仅使用键来迭代那些具有相关值的dataItem

 <xsl:for-each select="key('dataItems', name)">

此处,名称是您当前所在的当前元素下的名称元素。

这是一些更全面的XSLT,用于在上下文中显示 xsl:key 元素

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

   <xsl:key name="dataItems" match="dataItem" use="expression"/>

   <xsl:template match="root">
      <xsl:apply-templates select="lineage"/>
   </xsl:template>

   <xsl:template match="lineage">
      <xsl:for-each select="item">
         <Row>
            <Cell Borders="#ffffff">
               <xsl:attribute name="Background">
                  <xsl:choose>
                     <xsl:when test="position() mod 2 = 1">#CCCCFF</xsl:when>
                     <xsl:when test="position() mod 2 = 0">#FFFFFF</xsl:when>
                  </xsl:choose>
               </xsl:attribute>
               <Paddings Left="5" Right="5" Top="2" Bottom="2"/>
               <xsl:for-each select="key('dataItems', name)">
                  <Text Style="TableContent">
                     <xsl:value-of select="@name"/>
                  </Text>
               </xsl:for-each>
            </Cell>
            <Cell Borders="#ffffff">
               <xsl:attribute name="Background">
                  <xsl:choose>
                     <xsl:when test="position() mod 2 = 1">#CCCCFF</xsl:when>
                     <xsl:when test="position() mod 2 = 0">#FFFFFF</xsl:when>
                  </xsl:choose>
               </xsl:attribute>
               <Paddings Left="5" Right="5" Top="2" Bottom="2"/>
               <Text Style="TableContent">
                  <xsl:choose>
                     <xsl:when test="qi">
                        <xsl:value-of select="qi"/>
                     </xsl:when>
                     <xsl:otherwise>
                        <Text>N/A</Text>
                     </xsl:otherwise>
                  </xsl:choose>
               </Text>
            </Cell>
         </Row>
      </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>