【问题标题】:XSLT comparing values from different branches of XML documentXSLT 比较来自不同 XML 文档分支的值
【发布时间】:2014-05-22 22:03:35
【问题描述】:

我需要 XSLT 方面的帮助...在输入 xml 中,我有:

<shop>
  <categories>
    <category categoryId="63" parentCategoryId="239">
      <name>Fruit</name>
    </category>
    <category categoryId="62" parentCategoryId="239">
      <name>Vegetable</name>
    </category>
    <category categoryId="60" parentCategoryId="221">
      <name>Furniture</name>
    </category>
    ...
  <categories>
  <products>
    <product productId="3" productCode="1.05">
      <name>Chair</name>
      <categories>
        <category>60</category>
      </categories>
    </product>
    <product productId="21" productCode="1.59">
      <name>Apple</name>
      <categories>
        <category>63</category>
      </categories>
    </product>
    ...
  </products>
</shop>

我需要创建产品列表,其中包含产品名称及其类别名称。我怎样才能做到这一点?这对我不起作用...

<xsl:stylesheet
   version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

  <xsl:template match="shop">
    <export>
      <xsl:apply-templates select="products" />
    </export>
  </xsl:template>


  <xsl:template match="products">
    <xsl:for-each select="product">
      <polozka>
        <product_name>
          <xsl:value-of select="name" />
        </product_name>
        <xsl:for-each select="/shop/categories/category">
          <xsl:if test="boolean(@categoryId = /shop/products/product/categories/category)">
            <category_name>
              <xsl:value-of select="name" />
            </category_name>
          </xsl:if>
        </xsl:for-each>
      </polozka>    
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

如果有人可以帮助我,我会很高兴...

【问题讨论】:

  • 你能添加一个你期望输出的样本吗?谢谢!

标签: xml xslt if-statement compare


【解决方案1】:

如果您想根据 @categoryId 查找 类别,请考虑使用键进行查找

<xsl:key name="category" match="category" use="@categoryId"/>

那么,假设每个产品只属于一个类别,您可以像这样简单地查找产品的类别名称

<xsl:value-of select="key('category', categories/category)/name"/>

试试这个 XSLT

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

   <xsl:key name="category" match="category" use="@categoryId"/>

   <xsl:template match="shop">
      <export>
         <xsl:apply-templates select="products"/>
      </export>
   </xsl:template>

   <xsl:template match="products">
      <xsl:for-each select="product">
         <polozka>
            <product_name>
               <xsl:value-of select="name"/>
            </product_name>
            <category_name>
               <xsl:value-of select="key('category', categories/category)/name"/>
            </category_name>
         </polozka>
      </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>

如果 Product 元素可以有多个字符,那么您需要使用 for-each 循环来代替

 <xsl:for-each select="categories/category">
     <category_name>
         <xsl:value-of select="key('category', .)/name"/>
     </category_name>
 </xsl:for-each>

【讨论】:

    【解决方案2】:

    您正在将每个类别的@CategoryId 与所有产品进行比较:

    @categoryId = /shop/products/product/categories/category
    

    这永远是正确的,因为每个产品都与现有的类别相关。

    您必须将其与当前产品的类别进行比较。为此,您不需要&lt;xsl:if&gt;。它可以用谓词来完成。用这个替换你的 for-each:

    <xsl:for-each select="/shop/categories/category[@categoryId = current()/categories/category]">
         <category_name>
             <xsl:value-of select="name" />
         </category_name>
    </xsl:for-each>
    

    现在它应该过滤掉与当前产品的类别不匹配的类别。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      • 1970-01-01
      • 2018-12-27
      • 2011-12-21
      • 1970-01-01
      相关资源
      最近更新 更多