在XSLT上遇到一点麻烦..我想我可能会以完全错误的方式解决这个问题 . 尝试用一行中具有特殊状态的物品的SKU显示客户名称...然后是特殊的客户2项目等然后第2部分(我还没有开始)没有状态的项目
所以对于这个XML文件,输出就是
Joe prod1 //special1
Joe prod3 //special2
Joe prod2 //no status
Joe prod4 //no status
Joe prod5 //no status
John Smith prod6 prod8 //special1
John Smith prod7 //no status
John Smith prod9 //no status
John Smith prod10 //no status
它现在有点工作,但问题是,如果没有special1或special2,我无法弄清楚如何使它不打印客户名称..
并且我不确定如何显示之后没有状态的那些 - 任何帮助都将非常感谢!
XML:
<customer>
<name>Joe</name>
<order>
<item>
<SKU>prod1</SKU>
<status>special1</status>
</item>
<item>
<SKU>prod2</SKU>
</item>
<item>
<SKU>prod3</SKU>
<status>special2</status>
</item>
<item>
<SKU>prod4</SKU>
</item>
<item>
<SKU>prod5</SKU>
</item>
</order>
</customer>
<customer
<name>John Smith</name>
<order>
<item>
<SKU>prod6</SKU>
<status>special1</status>
</item>
<item>
<SKU>prod7</SKU>
</item>
<item>
<SKU>prod8</SKU>
<status>special1</status>
</item>
<item>
<SKU>prod9</SKU>
</item>
<item>
<SKU>prod10</SKU>
</item>
</order>
XSLT:
<!DOCTYPE xsl:stylesheet[ <!ENTITY nl "
"> ]>
<xsl:template match="customer">
<xsl:value-of select="name" /><xsl:apply-templates select="order/item[status='special1']" /><xsl:text>&nl;</xsl:text>
<xsl:value-of select="name" /><xsl:apply-templates select="order/item[status='special2']" /><xsl:text>&nl;</xsl:text>
</xsl:template>
<xsl:template match="item[status='special1']"><xsl:text> </xsl:text><xsl:value-of select="SKU" /></xsl:template>
<xsl:template match="item[status=special2']"><xsl:text> </xsl:text><xsl:value-of select="SKU" /></xsl:template>
<xsl:template match="text()"/>
3 回答
你最简单的选择只是一个xsl:if
我假设你不知道先验的不同状态 . 因此,如果您不希望XML可维护(无需在每次添加其他状态时更改它),您可以使用以下解决方案:
这是'grouping'问题的一个例子 . 您正尝试通过客户和状态的组合对项目进行分组 . 解决这个问题的方法因您使用的是XSLT 1.0还是XSLT 2.0而有所不同 . 在XSLT 1.0中,您将使用一种名为Muenchian Grouping的技术 . 首先,通过定义一个键来保存要分组的节点 . 在这种情况下,您按 customer 和 item 进行分组
然后,对于您匹配的每个 customer 元素,您将获得每个 item 的不同 status 元素,如下所示:
基本上,这样做是为客户查看每个 item ,并选择在为status元素定义的密钥中首先出现的那个 .
然后,在匹配具有状态的项目的模板中,您可以获得具有相同状态的单个项目,如下所示:
选择没有状态的项目要容易得多
这是完整的XSLT
当应用于您的XML时,输出以下内容:
如果你使用的是XSLT2.0,它会变得有点简单,因为你可以让我们使用 xsl:for-each-group 来处理分组:
然后要使用组获取项目,请使用 current-group() 函数
这是完整的XSLT2.0样式表,它也应该输出相同的结果: