我是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>