Xml 根据从每个实体获取的行业对文档进行排序和显示

Xml 根据从每个实体获取的行业对文档进行排序和显示,xml,xslt,Xml,Xslt,我有一个.xml文件,其结构如下: <documents> <item> <title>Document Title</title> <customer>Customer Name1</customer> <description>Description 1 here</description> <image height="100" width="100">

我有一个.xml文件,其结构如下:

<documents>
<item>
    <title>Document Title</title>
    <customer>Customer Name1</customer>
    <description>Description 1 here</description>
    <image height="100" width="100"></image>
    <link filetype="pdf" language="English">/documents/document.pdf</link>
    <industry>Industry name 1</industry>
</item>
<item>
    <title>Document Title 2</title>
    <customer>Customer Name 2</customer>
    <description>Description 2 here</description>
    <image height="100" width="100"></image>
    <link filetype="pdf" language="English">/documents/document2.pdf</link>
    <industry>Industry name 2</industry>
</item>

文件标题
客户名称1
描述1在这里
/文件/document.pdf
行业名称1
文件标题2
客户名称2
描述2在这里
/文件/document2.pdf
行业名称2

我更喜欢使用XSL(我已经对它有了一点了解,而且我会很快理解它),我需要这样做:

<h2>Industry name 1</h2>
<div class="doc">
<h3>Document Title</h3>
<p>Description 1 here <a href="/documents/document.pdf">Download!</a></p>
</div>

<h2>Industry name 2</h2>
<div class="doc">
<h3>Document Title 2</h3>
<p>Description 2 here <a href="/documents/document.pdf">Download!</a></p>
</div>
行业名称1
文件标题
描述1在这里

行业名称2 文件标题2 描述2在这里

我完全困惑的是,如何从XML中动态获取行业,打印第一个行业,然后打印与该行业相关的所有文档,然后再转到第二个行业,然后是第三个行业,第四个行业,依此类推。当我开始怀疑这是否可能的时候,我认为XSL必须实际存储每个行业的“标签”,并比较它们,以便看看它是否已经拥有它。如果有,它不应该打印它,而只是打印其余的信息

我宁愿避免更改XML文件的模式,因为它在各地都在使用,已经用于其他目的。但是,我意识到这可能是必须的

还请注意,该文件完全未排序。添加的最新文件位于顶部,而与之关联的行业“标签”无关。然而,这是可以改变的


对我来说,这是一个很难解决的问题,如果它甚至可以使用纯XSL作为解析器的话?

这个XSLT 1.0转换:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kItemByInd" match="item"
  use="industry"/>

 <xsl:template match=
  "item[generate-id()
       =
        generate-id(key('kItemByInd', industry)[1])
       ]
  ">
  <h2><xsl:value-of select="industry"/></h2>

  <xsl:apply-templates mode="inGroup"
   select="key('kItemByInd', industry)"/>
 </xsl:template>

 <xsl:template match="item"/>

 <xsl:template match="item" mode="inGroup">
   <div class="doc">
     <h3><xsl:value-of select="title"/></h3>
     <p>
       <xsl:value-of select="description"/>
       <a href="{link}"> Download!</a>
     </p>
   </div>
 </xsl:template>
</xsl:stylesheet>
<h2>Industry name 1</h2>
<div class="doc">
   <h3>Document Title</h3>
   <p>Description 1 here<a href="/documents/document.pdf"> Download!</a>
   </p>
</div>
<div class="doc">
   <h3>Document Title 3</h3>
   <p>Description 3 here<a href="/documents/document3.pdf"> Download!</a>
   </p>
</div>

<h2>Industry name 2</h2>
<div class="doc">
   <h3>Document Title 2</h3>
   <p>Description 2 here<a href="/documents/document2.pdf"> Download!</a>
   </p>
</div>
<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <xsl:for-each-group select="item" group-by="industry">
    <h2><xsl:value-of select="industry"/></h2>
    <xsl:apply-templates select="current-group()"/>
  </xsl:for-each-group>
 </xsl:template>

  <xsl:template match="item">
   <div class="doc">
     <h3><xsl:value-of select="title"/></h3>
     <p>
       <xsl:value-of select="description"/>
       <a href="{link}"> Download!</a>
     </p>
   </div>
 </xsl:template>
</xsl:stylesheet>

此XSLT 1.0转换

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kItemByInd" match="item"
  use="industry"/>

 <xsl:template match=
  "item[generate-id()
       =
        generate-id(key('kItemByInd', industry)[1])
       ]
  ">
  <h2><xsl:value-of select="industry"/></h2>

  <xsl:apply-templates mode="inGroup"
   select="key('kItemByInd', industry)"/>
 </xsl:template>

 <xsl:template match="item"/>

 <xsl:template match="item" mode="inGroup">
   <div class="doc">
     <h3><xsl:value-of select="title"/></h3>
     <p>
       <xsl:value-of select="description"/>
       <a href="{link}"> Download!</a>
     </p>
   </div>
 </xsl:template>
</xsl:stylesheet>
<h2>Industry name 1</h2>
<div class="doc">
   <h3>Document Title</h3>
   <p>Description 1 here<a href="/documents/document.pdf"> Download!</a>
   </p>
</div>
<div class="doc">
   <h3>Document Title 3</h3>
   <p>Description 3 here<a href="/documents/document3.pdf"> Download!</a>
   </p>
</div>

<h2>Industry name 2</h2>
<div class="doc">
   <h3>Document Title 2</h3>
   <p>Description 2 here<a href="/documents/document2.pdf"> Download!</a>
   </p>
</div>
<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <xsl:for-each-group select="item" group-by="industry">
    <h2><xsl:value-of select="industry"/></h2>
    <xsl:apply-templates select="current-group()"/>
  </xsl:for-each-group>
 </xsl:template>

  <xsl:template match="item">
   <div class="doc">
     <h3><xsl:value-of select="title"/></h3>
     <p>
       <xsl:value-of select="description"/>
       <a href="{link}"> Download!</a>
     </p>
   </div>
 </xsl:template>
</xsl:stylesheet>

是否要按行业对文档进行分组?@empo是的,它们需要分组并在上面的h2标记中具有行业名称。是否要按行业对文档进行分组?@empo是的,它们需要分组并在上面的h2标记中具有行业名称。太棒了!我无法让看似简单的2.0版本正常工作,但1.0方式运行良好。是否也可以按字母表对行业进行排序?通常我只会添加xsl:sort,但这不会出现在模板中,那么还有其他方法吗?@Patrik Alienus:要运行XSLT 2.0转换,您需要一个XSLT 2.0处理器。如果您刚刚开始使用XSLT,我强烈建议您从一开始就使用XSLT2.0。至于按行业排序,是的,这是可以做到的,但是在第一个解决方案中,我们必须有一个明确的
,作为一个孩子
。对于第二种解决方案,只需将
子级添加到
。是的,我想使用2.0,但遗憾的是,由于服务器限制,我不能使用。但是,您所说的“显式”是什么意思?我注意到简单地将
添加到
中是不起作用的。。。所以我想我真正的问题是,显式的
到哪里去了?@Patrik Alienus:我用XSLT 1.0解决方案的一个变体更新了我的答案(看最后),该解决方案还按照
行业对组进行了排序!我无法让看似简单的2.0版本正常工作,但1.0方式运行良好。是否也可以按字母表对行业进行排序?通常我只会添加xsl:sort,但这不会出现在模板中,那么还有其他方法吗?@Patrik Alienus:要运行XSLT 2.0转换,您需要一个XSLT 2.0处理器。如果您刚刚开始使用XSLT,我强烈建议您从一开始就使用XSLT2.0。至于按行业排序,是的,这是可以做到的,但是在第一个解决方案中,我们必须有一个明确的
,作为一个孩子
。对于第二种解决方案,只需将
子级添加到
。是的,我想使用2.0,但遗憾的是,由于服务器限制,我不能使用。但是,您所说的“显式”是什么意思?我注意到简单地将
添加到
中是不起作用的。。。因此,我想我真正的问题是,显式的
去哪里了?@Patrik Alienus:我已经用XSLT 1.0解决方案的变体更新了我的答案(看最后),该解决方案还按照
行业对组进行排序