我是XSLT的新手,我正在尝试编写一些XSLT,它将平整任何给定的XML,以便每当嵌套级别发生更改时就会出现新行。我的输入可以是具有任何数量的嵌套级别的任何XML文档,因此XSLT不知道其结构。由于我可以使用这些工具,因此我的解决方案必须使用XSLT 1.0版。
例如。
<?xml version="1.0"?>
<ROWSET>
<ROW>
<CUSTOMER_ID>0</CUSTOMER_ID>
<NAME>Default Company</NAME>
<BONUSES>
<BONUSES_ROW>
<BONUS_ID>21</BONUS_ID>
<DESCRIPTION>Performance Bonus</DESCRIPTION>
</BONUSES_ROW>
<BONUSES_ROW>
<BONUS_ID>26</BONUS_ID>
<DESCRIPTION>Special Bonus</DESCRIPTION>
</BONUSES_ROW>
</BONUSES>
</ROW>
<ROW>
<CUSTOMER_ID>1</CUSTOMER_ID>
<NAME>Dealer 1</NAME>
<BONUSES>
<BONUSES_ROW>
<BONUS_ID>27</BONUS_ID>
<DESCRIPTION>June Bonus</DESCRIPTION>
<BONUS_VALUES>
<BONUS_VALUES_ROW>
<VALUE>10</VALUE>
<PERCENT>N</PERCENT>
</BONUS_VALUES_ROW>
<BONUS_VALUES_ROW>
<VALUE>11</VALUE>
<PERCENT>Y</PERCENT>
</BONUS_VALUES_ROW>
</BONUS_VALUES>
</BONUSES_ROW>
</BONUSES>
</ROW>
</ROWSET>
需要成为...。
0, Default Company
21, Performance Bonus
26, Special Bonus
1, Dealer 1
27, June Bonus
10, N
11, Y
到目前为止,我写的XSLT是...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:strip-space elements="*" />
<xsl:template match="/*/child::*">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*">
<xsl:value-of select="text()" />
<xsl:if test="position()!= last()"><xsl:text>,</xsl:text></xsl:if>
<xsl:if test="position()= last()"><xsl:text>
</xsl:text></xsl:if>
<xsl:apply-templates select="./child::*"/>
</xsl:template>
</xsl:stylesheet>
但是我的输出是不正确的,有空白和不必要的数据。
0,Default Company,
,21,Performance Bonus
26,Special Bonus
1,Dealer 1,
27,June Bonus,
,10,N
11,Y
似乎需要检查节点是否可以包含文本,但是我受困于此,可以在XSLT专家的帮助下进行。
最佳答案
您可以通过执行以下操作来测试元素是否具有文本:*[text()]
例...
XML输入
<ROWSET>
<ROW>
<CUSTOMER_ID>0</CUSTOMER_ID>
<NAME>Default Company</NAME>
<BONUSES>
<BONUSES_ROW>
<BONUS_ID>21</BONUS_ID>
<DESCRIPTION>Performance Bonus</DESCRIPTION>
</BONUSES_ROW>
<BONUSES_ROW>
<BONUS_ID>26</BONUS_ID>
<DESCRIPTION>Special Bonus</DESCRIPTION>
</BONUSES_ROW>
</BONUSES>
</ROW>
<ROW>
<CUSTOMER_ID>1</CUSTOMER_ID>
<NAME>Dealer 1</NAME>
<BONUSES>
<BONUSES_ROW>
<BONUS_ID>27</BONUS_ID>
<DESCRIPTION>June Bonus</DESCRIPTION>
<BONUS_VALUES>
<BONUS_VALUES_ROW>
<VALUE>10</VALUE>
<PERCENT>N</PERCENT>
</BONUS_VALUES_ROW>
<BONUS_VALUES_ROW>
<VALUE>11</VALUE>
<PERCENT>Y</PERCENT>
</BONUS_VALUES_ROW>
</BONUS_VALUES>
</BONUSES_ROW>
</BONUSES>
</ROW>
</ROWSET>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[text()]">
<xsl:if test="position() > 1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:value-of select="."/>
<xsl:if test="not(following-sibling::*[text()])">
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
文本输出
0, Default Company
21, Performance Bonus
26, Special Bonus
1, Dealer 1
27, June Bonus
10, N
11, Y
另外,看看Built-in Template Rules,看看是什么使该样式表仅适用于一个模板。
编辑
此样式表还将为空元素输出一个逗号:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[text() or not(*)]">
<xsl:if test="position() > 1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:value-of select="."/>
<xsl:if test="not(following-sibling::*[text() or not(*)])">
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>