我有一个.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>
我需要这个,最好使用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>
我完全难以理解的是,我是如何动态地从XML中获取行业,打印第一个行业,然后打印与该行业相关的所有文档,然后转到第二个行业,然后是第三个行业,第四个行业等等。我开始怀疑这是否可能,当我认为XSL必须实际存储每个行业的“标签”并比较它们以便看它是否已经拥有它。如果是,则不应打印,而只是打印其余信息。
我宁愿避免更改XML文件的架构,因为它已在所有已经用于其他目的的地方使用。但是,我意识到它可能是必须的。
另请注意,该文件完全未分类。添加的最新文件位于顶部,无论与之关联的行业“标记”如何。但是,这可以改变。
对我来说,如果它甚至可以使用纯XSL作为解析器,这是一个难以破解的难题吗?
答案 0 :(得分:1)
此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>
应用于以下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>
<item>
<title>Document Title 3</title>
<customer>Customer Name 3</customer>
<description>Description 3 here</description>
<image height="100" width="100"></image>
<link filetype="pdf" language="English">/documents/document3.pdf</link>
<industry>Industry name 1</industry>
</item>
</documents>
生成想要的正确结果:
<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>
,它在浏览器中显示为:
说明1 Download!
说明3 Download!
说明2 Download!
解释: Muenchian method for grouping 。
<强> II。 XSLT 2.0解决方案:
<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>
当对同一XML文档(上面)应用此XSLT 2.0转换时,再次生成相同的正确结果。
<强>解释强>:
更新:根据OP的请求,以下是XSLT 1.0解决方案的变体,它也按industry
排序:
<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="/*">
<xsl:apply-templates select=
"item[generate-id()
=
generate-id(key('kItemByInd', industry)[1])
]
">
<xsl:sort select="industry"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="item">
<h2><xsl:value-of select="industry"/></h2>
<xsl:apply-templates mode="inGroup"
select="key('kItemByInd', industry)"/>
</xsl:template>
<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>