【问题标题】:XSLT for grouping and restructuring XML based on parent node基于父节点对 XML 进行分组和重组的 XSLT
【发布时间】:2017-04-10 10:40:07
【问题描述】:

我有这样结构的 XML 文件-

<products>
 <product>
  <id>1</id>
  <type>fruits</type>
  <varieties>
   <variety>
    <id>a</id>
    <cost>100</cost>
    <availability>Y</availability>
   </variety>
   <variety>
    <id>b</id>
    <cost>75</cost>
    <availability>N</availability>
   </variety>
  </varieties>
 </product>
 <product>
  <id>2</id>
  <type>vegetables</type>
  <varieties>
   <variety>
    <id>c</id>
    <cost>50</cost>
    <availability>Y</availability>
   </variety>
   <variety>
    <id>d</id>
    <cost>55</cost>
    <availability>Y</availability>
   </variety>
  </varieties>
 </product>
</products>

我想根据产品/产品/id 重构给定的 XML。预期输出如下-

<html>
 <body>
  <table border="1">
  <tr> 
   <td>1</td>
   <td>fruits</td>
   <td>a</td>
   <td>100</td>
   <td>Y</td>
  </tr> 
  <tr> 
   <td>1</td>
   <td>fruits</td>
   <td>b</td>
   <td>75</td>
   <td>N</td>
  </tr>  
  <tr> 
   <td>2</td>
   <td>vegetables</td>
   <td>c</td>
   <td>50</td>
   <td>Y</td>
  </tr> 
  <tr> 
   <td>2</td>
   <td>vegetables</td>
   <td>d</td>
   <td>55</td>
   <td>Y</td>
  </tr>
  </table>
 </body>
</html>

我已经尝试过这个 XSLT,但它没有返回预期的 xml。

<xsl:stylesheet version="1.0"    
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
 <products>
  <product>
   <varieties>
    <xsl:apply-templates select="products/product/varieties/variety" /> 
   </varieties>
  </product>
 </products>
</xsl:template>
<xsl:template match="products" >
<html>
 <body>
  <table border="1">
   <xsl:for-each select="products/product">
    <tr>
     <td><xsl:value-of select="id" /></td>
     <td><xsl:value-of select="type" /></td>
     <xsl:for-each select="varieties/variety" >
      <td><xsl:value-of select="id" /></td>
      <td><xsl:value-of select="cost" /></td>
      <td><xsl:value-of select="availability" /></td>
     </xsl:for-each>
    </tr> 
   </xsl:for-each>
  </table>
 </body>
</html>
</xsl:template>      
</xsl:stylesheet>

【问题讨论】:

  • 您正在将模板应用于“variety” - 但您没有与variety 匹配的模板。您有一个匹配 root 的模板 - 但没有名为 root 的元素。并且匹配/(这是唯一被执行的模板)的模板的内容与您的预期输出不匹配。
  • 另请注意,XML 区分大小写:varietyVariety 不匹配。
  • 嗨@michael.hor257k 我已经修改了我的XSLT。能否请您提出更改建议?
  • 没有。这确实是一项微不足道的任务。为每个variety创建一行,并使用&lt;xsl:value-of select="../../id" /&gt;&lt;xsl:value-of select="../../type"/&gt;分别获取祖先产品的id和type。

标签: xml xslt xslt-1.0


【解决方案1】:

你需要匹配/products,所以下面应该给你你想要的

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/products" >
<html>
 <body>
  <table border="1">
   <xsl:for-each select="product">
    <tr>
     <td><xsl:value-of select="id" /></td>
     <td><xsl:value-of select="type" /></td>
     <xsl:for-each select="varieties/variety" >
      <td><xsl:value-of select="id" /></td>
      <td><xsl:value-of select="cost" /></td>
      <td><xsl:value-of select="availability" /></td>
     </xsl:for-each>
    </tr> 
   </xsl:for-each>
  </table>
 </body>
</html>
</xsl:template>      
</xsl:stylesheet>

恕我直言,如果每种产品的品种数量不同,您的 html 输出可能会非常混乱。我不了解您的应用程序,但您可能需要考虑根据品种数在前 2 列上使用行跨度,并且每个品种有一行。

根据 OP 反馈更新

我已经包含了跨越重复数据的代码,如果您不喜欢,请随意删除 if 开始和结束标记并删除 rowspan 属性

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/products" >
<html>
 <body>
     <table border="1">
        <xsl:for-each select="product">
        <xsl:variable name="ProductID" select="id"/>
        <xsl:variable name="ProductType" select="type"/>
        <xsl:variable name="VarietyCount" select="count(varieties/variety)"/>
         <xsl:for-each select="varieties/variety" >
            <tr>
                <xsl:if test="position() = 1">
                     <td rowspan="{$VarietyCount}"><xsl:value-of select="$ProductID" /></td>
                     <td rowspan="{$VarietyCount}"><xsl:value-of select="$ProductType" /></td>
                </xsl:if>
                  <td><xsl:value-of select="id" /></td>
                  <td><xsl:value-of select="cost" /></td>
                  <td><xsl:value-of select="availability" /></td>
            </tr> 
            </xsl:for-each>
        </xsl:for-each>
     </table>
 </body>
</html>
</xsl:template>      
</xsl:stylesheet>

【讨论】:

  • 嗨@RT72,您给定的XSLT 将'' 下的所有元素返回到一个列表中。我的要求是列出每个节点“”中的所有元素及其父节点元素“”。
  • 我不清楚你的意思,我得到了你在原始帖子中给出的确切结果 - 你想要不同的输出 - 如果是的话,你可以更新你的问题来澄清吗?
  • 嗨@RT72,我需要在这里应用类似分组概念的东西。让我解释一下这个概念。我有 2 个产品 。在每种产品下,我都有 2 个品种,它们用 进行引用。现在,我想根据品种对 XML 中的元素进行分组,每个组应具有以下元素 - (水果/蔬菜的 ID)、(水果/蔬菜)、(品种的 ID) , , .
  • 所以我明白了,您是说您想要 XML 输出而不是原始帖子建议的 html 输出?
  • 我可以使用 XML 或 HTML 格式来获取所需条件的数据。但最好是 HTML。
猜你喜欢
  • 2015-05-15
  • 2021-03-14
  • 1970-01-01
  • 2018-04-20
  • 2014-06-10
  • 1970-01-01
  • 2012-08-07
  • 1970-01-01
相关资源
最近更新 更多