我是XML和XSLT的新手。我正在尝试将带有逗号分隔的XML文件中的特定节点分开。我已经看到了一个可以做到的代码,然后尝试将其组合在XSLT文件中。它有效,但是输出包含所有节点,而忽略了我的希望路径。这是我的XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<fortnight>
<hero>
<name>Guardian</name>
<characters>Bull,Knox,Penny</characters>
<rarities>Rare,Epic,Legendary</rarities>
</hero>
<hero>
<name>Deadly Blade</name>
<characters>Crash,Scorpion</characters>
<rarities>Epic,Legendary</rarities>
</hero>
<hero>
<name>Enforcer</name>
<characters>Grizzly</characters>
<rarities>Uncommon,Rare,Epic,Legendary</rarities>
</hero>
</fortnight>
这是我的XSLT文件。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
<characters>
<xsl:apply-templates select="hero" />
<xsl:value-of select="characters" />
</characters>
</xsl:template>
<xsl:template match="text()" name="split">
<xsl:param name="pText" select="."/>
<xsl:if test="string-length($pText) >0">
<character name="character">
<xsl:value-of select=
"substring-before(concat($pText, ','), ',')"/>
</character>
<xsl:call-template name="split">
<xsl:with-param name="pText" select=
"substring-after($pText, ',')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
仅使用"字符"节点,如何调整XSLT以创建输出文件,如果一个节点包含逗号,它将在输出中将它们分开?
做<xsl:apply-templates select="hero" />
时,您会在fortnight
下选择所有hero
元素,然后XSLT寻找用于应用于它们的模板。但是,在您的XSLT中没有匹配hero
的模板。发生这种情况时,XSLT的内置模板规则适用。在这种情况下,将应用以下模板
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
因此,有效地,它将选择XML中的所有内容,直到到达文本节点为止。不仅是characters
下的文本节点,还包括所有文本节点。
您需要做的是仅定位您要分裂的节点。这意味着用<xsl:apply-templates select="hero/characters" />
替换<xsl:apply-templates select="hero" />
。
还要注意可以删除该行<xsl:value-of select="characters" />
。因为这是在匹配fortnight
的模板中,这只会选择characters
元素,该元素是fortnight
的直接孩子。
尽管您还没有向我们展示转换的想要的结果,但我相信此转换可能很有用:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="text()"/>
<xsl:template match="/">
<characters><xsl:apply-templates/></characters>
</xsl:template>
<xsl:template match="characters/text()" name="split">
<xsl:param name="pText" select="."/>
<xsl:if test="string-length($pText) > 0">
<character name="character">
<xsl:value-of select=
"substring-before(concat($pText, ','), ',')"/>
</character>
<xsl:call-template name="split">
<xsl:with-param name="pText" select=
"substring-after($pText, ',')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于提供的源XML文档:
<fortnight>
<hero>
<name>Guardian</name>
<characters>Bull,Knox,Penny</characters>
<rarities>Rare,Epic,Legendary</rarities>
</hero>
<hero>
<name>Deadly Blade</name>
<characters>Crash,Scorpion</characters>
<rarities>Epic,Legendary</rarities>
</hero>
<hero>
<name>Enforcer</name>
<characters>Grizzly</characters>
<rarities>Uncommon,Rare,Epic,Legendary</rarities>
</hero>
</fortnight>
(最可能(想要的结果:
<characters>
<character name="character">Bull</character>
<character name="character">Knox</character>
<character name="character">Penny</character>
<character name="character">Crash</character>
<character name="character">Scorpion</character>
<character name="character">Grizzly</character>
</characters>