XSLT 1.0 - 多个子节点格式化输出
XSLT 1.0 - Multiple Child Nodes Formatted Output
我可以用 For-Each 做到这一点,但在 Apply_Templates 中有一些问题。
XML 数据包含不同的子节点,但我想显示所有子节点及其父节点信息。
<orders>
<order>
<customer>1</customer>
<items>
<item>
<name>Widget A</name>
<price>10</price>
<code>1A</code>
</item>
</items>
</order>
<order>
<customer>2</customer>
<items>
<item>
<name>Widget A</name>
<price>10</price>
<code>1A</code>
</item>
</items>
<items>
<item>
<name>Widget B</name>
<price>20</price>
<code>2B</code>
</item>
</items>
</order>
<order>
<customer>3</customer>
<items>
<item>
<name>Widget A</name>
<price>10</price>
<code>1A</code>
</item>
</items>
<items>
<item>
<name>Widget B</name>
<price>10</price>
<code>1A</code>
</item>
</items>
<items>
<item>
<name>Widget C</name>
<price>30</price>
<code>3C</code>
</item>
</items>
</order>
如您所见,每个客户每个订单有多个项目。我希望输出看起来像这样:
Customer, Name, Price, Code
1, Widget A, 10, 1A
2, Widget A, 10, 1A
2, Widget B, 20, 2B
3, Widget A, 10, 1A
3, Widget B, 20, 2B
3, Widget C, 30, 3C
当我应用模板时,我只能显示第一个项目而不能显示其他项目。如果您认为我应该 post 我的 XSL,请告诉我,但我认为它应该很简单,只是卡住了。我想摆脱使用 for-each。
你可以这样试试:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:text>Customer, Name, Price ,Code
</xsl:text>
<xsl:apply-templates select="//item"/>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="../../customer"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="name"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="price"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="code"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
第一个模板匹配根元素并在输出文档中打印header。
第二个模板匹配item
个元素,输出对应的comma-separated个值。这样您就可以在输出文档中获得来自每个 item
的行,而无需使用 for-each
构造。
我相信真正基于模板的方法应该是这样的:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/orders">
<xsl:text>Customer, Name, Price, Code </xsl:text>
<xsl:apply-templates select="order/items/item"/>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="../../customer"/>
<xsl:text>, </xsl:text>
<xsl:apply-templates/>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="item/*">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
但是,正如我在对您的问题的评论中提到的,除了将代码分解成难以理解的不连续块之外,这没有明显的目的。
我可以用 For-Each 做到这一点,但在 Apply_Templates 中有一些问题。
XML 数据包含不同的子节点,但我想显示所有子节点及其父节点信息。
<orders>
<order>
<customer>1</customer>
<items>
<item>
<name>Widget A</name>
<price>10</price>
<code>1A</code>
</item>
</items>
</order>
<order>
<customer>2</customer>
<items>
<item>
<name>Widget A</name>
<price>10</price>
<code>1A</code>
</item>
</items>
<items>
<item>
<name>Widget B</name>
<price>20</price>
<code>2B</code>
</item>
</items>
</order>
<order>
<customer>3</customer>
<items>
<item>
<name>Widget A</name>
<price>10</price>
<code>1A</code>
</item>
</items>
<items>
<item>
<name>Widget B</name>
<price>10</price>
<code>1A</code>
</item>
</items>
<items>
<item>
<name>Widget C</name>
<price>30</price>
<code>3C</code>
</item>
</items>
</order>
如您所见,每个客户每个订单有多个项目。我希望输出看起来像这样:
Customer, Name, Price, Code
1, Widget A, 10, 1A
2, Widget A, 10, 1A
2, Widget B, 20, 2B
3, Widget A, 10, 1A
3, Widget B, 20, 2B
3, Widget C, 30, 3C
当我应用模板时,我只能显示第一个项目而不能显示其他项目。如果您认为我应该 post 我的 XSL,请告诉我,但我认为它应该很简单,只是卡住了。我想摆脱使用 for-each。
你可以这样试试:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:text>Customer, Name, Price ,Code
</xsl:text>
<xsl:apply-templates select="//item"/>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="../../customer"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="name"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="price"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="code"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
第一个模板匹配根元素并在输出文档中打印header。
第二个模板匹配
item
个元素,输出对应的comma-separated个值。这样您就可以在输出文档中获得来自每个item
的行,而无需使用for-each
构造。
我相信真正基于模板的方法应该是这样的:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/orders">
<xsl:text>Customer, Name, Price, Code </xsl:text>
<xsl:apply-templates select="order/items/item"/>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="../../customer"/>
<xsl:text>, </xsl:text>
<xsl:apply-templates/>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="item/*">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
但是,正如我在对您的问题的评论中提到的,除了将代码分解成难以理解的不连续块之外,这没有明显的目的。