Web应用程序为我提供了一个XML-feed,我无法改变。我想要做的是将这个XML-feed分成几个无序列表。我试图用下面的XSLT来做这件事。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" encoding="utf-8" />
<xsl:param name="html-content-type" />
<xsl:template match="/NavigationTree">
<xsl:if test="count(//Page) > 0">
<ul>
<xsl:apply-templates select="Page">
</xsl:apply-templates>
</ul>
</xsl:if>
</xsl:template>
<xsl:template match="//Page">
<li class="{position() mod 3}">
<xsl:text disable-output-escaping="yes"><![CDATA[» ]]></xsl:text>
<a>
<xsl:attribute name="href">
<xsl:value-of select="@FriendlyHref" disable-output-escaping="yes"/>
</xsl:attribute>
<xsl:value-of select="@MenuText" disable-output-escaping="no"/>
</a>
</li>
<xsl:if test="position() mod 3 = 0">
<xsl:if test="position() < count(//Page)">
<!--Don't know if this is the correct approach, but when the position is 3 and there are more items following
I want to create an new unordered list-->
</xsl:if>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
使用上面的XSLT,我可以将XML转换为无序列表,其中包含6个项目(让我们假设总共有6个项目)。与下面的例子类似;
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
<li>Item4</li>
<li>Item5</li>
<li>Item6</li>
</ul>
上面的例子是我现在得到的结果。但是期望的结果是这样的;
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
</ul>
<ul>
<li>Item4</li>
<li>Item5</li>
<li>Item6</li>
</ul>
编辑 - 示例XML输入
<NavigationTree>
<Settings>
<!--Snipped data-->
</Settings>
<Page ID="5" AreaID="1" MenuText="Bestellen" MouseOver="" Href="Default.aspx?ID=5" FriendlyHref="/nl-nl/klantenservice/bestellen.aspx" Image="" ImageActive="" ImageMouseOver="" Title="" Allowclick="True" ShowInSitemap="True" ShowInLegend="True" AbsoluteLevel="2" RelativeLevel="2" Sort="1" LastInLevel="False" InPath="False" ChildCount="0" class="L2" Active="False" IsPagePasswordProtected="False" IsPageUserProtected="False" CanAccessPasswordProtectedPage="False" CanAccessUserProtectedPage="True"/>
<Page ID="6" AreaID="1" MenuText="Betalen" MouseOver="" Href="Default.aspx?ID=6" FriendlyHref="/nl-nl/klantenservice/betalen.aspx" Image="" ImageActive="" ImageMouseOver="" Title="" Allowclick="True" ShowInSitemap="True" ShowInLegend="True" AbsoluteLevel="2" RelativeLevel="2" Sort="2" LastInLevel="False" InPath="True" ChildCount="0" class="L2_Active" Active="True" IsPagePasswordProtected="False" IsPageUserProtected="False" CanAccessPasswordProtectedPage="False" CanAccessUserProtectedPage="True"/>
<Page ID="7" AreaID="1" MenuText="Retourneren" MouseOver="" Href="Default.aspx?ID=7" FriendlyHref="/nl-nl/klantenservice/retourneren.aspx" Image="" ImageActive="" ImageMouseOver="" Title="" Allowclick="True" ShowInSitemap="True" ShowInLegend="True" AbsoluteLevel="2" RelativeLevel="2" Sort="3" LastInLevel="False" InPath="False" ChildCount="0" class="L2" Active="False" IsPagePasswordProtected="False" IsPageUserProtected="False" CanAccessPasswordProtectedPage="False" CanAccessUserProtectedPage="True"/>
<Page ID="8" AreaID="1" MenuText="Garantie" MouseOver="" Href="Default.aspx?ID=8" FriendlyHref="/nl-nl/klantenservice/garantie.aspx" Image="" ImageActive="" ImageMouseOver="" Title="" Allowclick="True" ShowInSitemap="True" ShowInLegend="True" AbsoluteLevel="2" RelativeLevel="2" Sort="4" LastInLevel="False" InPath="False" ChildCount="0" class="L2" Active="False" IsPagePasswordProtected="False" IsPageUserProtected="False" CanAccessPasswordProtectedPage="False" CanAccessUserProtectedPage="True"/>
<Page ID="9" AreaID="1" MenuText="Faq" MouseOver="" Href="Default.aspx?ID=9" FriendlyHref="/nl-nl/klantenservice/veel-gestelde-vragen.aspx" Image="" ImageActive="" ImageMouseOver="" Title="" Allowclick="True" ShowInSitemap="True" ShowInLegend="True" AbsoluteLevel="2" RelativeLevel="2" Sort="5" LastInLevel="False" InPath="False" ChildCount="0" class="L2" Active="False" IsPagePasswordProtected="False" IsPageUserProtected="False" CanAccessPasswordProtectedPage="False" CanAccessUserProtectedPage="True"/>
<Page ID="10" AreaID="1" MenuText="Contact" MouseOver="" Href="Default.aspx?ID=10" FriendlyHref="/nl-nl/klantenservice/contact.aspx" Image="" ImageActive="" ImageMouseOver="" Title="" Allowclick="True" ShowInSitemap="True" ShowInLegend="True" AbsoluteLevel="2" RelativeLevel="2" Sort="6" LastInLevel="True" InPath="False" ChildCount="0" class="L2" Active="False" IsPagePasswordProtected="False" IsPageUserProtected="False" CanAccessPasswordProtectedPage="False" CanAccessUserProtectedPage="True"/>
</NavigationTree>
如您所见,我总是希望以3个项目为一组进行输出。使用XSLT可以实现这种html输出吗?如果是,我该怎么做?欢迎任何帮助!
答案 0 :(得分:10)
<强>予。 XSLT 1.0
这是一个简短的参数化解决方案,展示了如何将兄弟元素拆分为预定义大小的组。使用 No 显式条件XSLT指令:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pGroupSize" select="3"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<nums>
<xsl:apply-templates select=
"num[position() mod $pGroupSize = 1]"/>
</nums>
</xsl:template>
<xsl:template match="num">
<group>
<xsl:copy-of select=
".|following-sibling::*
[not(position() > $pGroupSize -1)]"/>
</group>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下XML文档:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
产生了想要的正确结果:
<nums>
<group>
<num>01</num>
<num>02</num>
<num>03</num>
</group>
<group>
<num>04</num>
<num>05</num>
<num>06</num>
</group>
<group>
<num>07</num>
<num>08</num>
<num>09</num>
</group>
<group>
<num>10</num>
</group>
</nums>
<强> 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:param name="pGroupSize" select="3"/>
<xsl:template match="/*">
<nums>
<xsl:for-each-group select="*"
group-by="(position() -1) idiv $pGroupSize">
<group>
<xsl:sequence select="current-group()"/>
</group>
</xsl:for-each-group>
</nums>
</xsl:template>
</xsl:stylesheet>
当此转换应用于同一XML文档(上图)时,会产生相同的正确结果:
<nums>
<group>
<num>01</num>
<num>02</num>
<num>03</num>
</group>
<group>
<num>04</num>
<num>05</num>
<num>06</num>
</group>
<group>
<num>07</num>
<num>08</num>
<num>09</num>
</group>
<group>
<num>10</num>
</group>
</nums>
解释:
使用<xsl:for-each-group>
所选节点按其所属群组的序号分组。
使用标准XSLT 2.0函数current-group()
。
答案 1 :(得分:8)
要执行此操作,您需要匹配 Page 元素,即位置1,4,7等...换句话说,其中 position()mod 3 等于1。
<xsl:if test="position() mod 3 = 1">
这给出了列表的第一个元素。然后你可以在其中获得剩余的2个元素,如此
<xsl:apply-templates select=".|following-sibling::Page[position() < 3]" mode="list"/>
完全放弃,给出以下XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" encoding="utf-8"/>
<xsl:param name="html-content-type"/>
<xsl:param name="group-size" select="3"/>
<xsl:template match="/NavigationTree">
<xsl:if test="count(//Page) > 0">
<xsl:apply-templates select="Page"/>
</xsl:if>
</xsl:template>
<xsl:template match="Page">
<xsl:if test="position() mod $group-size = 1">
<ul>
<xsl:apply-templates select=".|following-sibling::Page[position() < $group-size]" mode="list"/>
</ul>
</xsl:if>
</xsl:template>
<xsl:template match="Page" mode="list">
<li class="{position()}">
<xsl:text disable-output-escaping="yes"><![CDATA[» ]]></xsl:text>
<a>
<xsl:attribute name="href">
<xsl:value-of select="@FriendlyHref" disable-output-escaping="yes"/>
</xsl:attribute>
<xsl:value-of select="@MenuText" disable-output-escaping="no"/>
</a>
</li>
</xsl:template>
</xsl:stylesheet>
在输入XML上运行时,应生成以下输出
<ul>
<li class="1">» <a href="/nl-nl/klantenservice/bestellen.aspx">Bestellen</a></li>
<li class="2">» <a href="/nl-nl/klantenservice/betalen.aspx">Betalen</a></li>
<li class="3">» <a href="/nl-nl/klantenservice/retourneren.aspx">Retourneren</a></li>
</ul>
<ul>
<li class="1">» <a href="/nl-nl/klantenservice/garantie.aspx">Garantie</a></li>
<li class="2">» <a href="/nl-nl/klantenservice/veel-gestelde-vragen.aspx">Faq</a></li>
<li class="3">» <a href="/nl-nl/klantenservice/contact.aspx">Contact</a></li>
</ul>
请注意我已经参数化了组大小,例如,您可以轻松地将每个列表更改为4或5个元素。
答案 2 :(得分:3)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" encoding="utf-8" />
<xsl:template match="/NavigationTree">
<xsl:apply-templates select="Page[position() mod 3 = 1]" mode="ul"/>
</xsl:template>
<xsl:template match="Page" mode="li">
<li class="{position() mod 3}">
<a href="{@FriendlyHref}">
<xsl:value-of select="@MenuText" disable-output-escaping="no"/>
</a>
</li>
</xsl:template>
<xsl:template match="Page" mode="ul">
<ul>
<xsl:apply-templates select=". | following-sibling::Page[position() < 3]" mode="li"/>
</ul>
</xsl:template>
</xsl:stylesheet>
输出:
<ul>
<li class="1">
<a href="/nl-nl/klantenservice/bestellen.aspx">Bestellen</a>
</li>
<li class="2">
<a href="/nl-nl/klantenservice/betalen.aspx">Betalen</a>
</li>
<li class="0">
<a href="/nl-nl/klantenservice/retourneren.aspx">Retourneren</a>
</li>
</ul>
<ul>
<li class="1">
<a href="/nl-nl/klantenservice/garantie.aspx">Garantie</a>
</li>
<li class="2">
<a href="/nl-nl/klantenservice/veel-gestelde-vragen.aspx">Faq</a>
</li>
<li class="0">
<a href="/nl-nl/klantenservice/contact.aspx">Contact</a>
</li>
</ul>