XML和XSLT-单独的节点包括逗号

XML和XSLT-单独的节点包括逗号,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我不熟悉XML和XSLT。我试图在XML文件中分隔一个特定的节点,用逗号分隔。我已经看到了一个实现这一点的代码,并尝试将其组合到XSLT文件中。它可以工作,但输出包含所有节点,并忽略我希望的路径。 这是我的XML文件: <?xml version="1.0" encoding="UTF-8"?> <fortnight> <hero> <name>Guardian</name> <charac

我不熟悉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来创建一个输出文件,只使用characters节点,如果节点包含逗号,它将在输出中分隔它们

当您这样做时,您可以选择“两周”下的所有child-hero元素,然后XSLT查找要应用于这些元素的模板。但是,XSLT中没有与hero匹配的模板。当这种情况发生时,XSLT将应用。在这种情况下,将应用以下模板

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>
因此,它将有效地选择XML中的所有内容,直到到达文本节点。不仅仅是字符下的文本节点,而是所有文本节点

您需要做的是,只针对要拆分的节点。这意味着要用新的替代


另请注意,可以拆下该线路。由于这是在模板匹配两周中,因此只会选择作为两周的直接子元素的字符元素,其中没有任何字符元素。

虽然您尚未向我们展示转换的预期结果,但我相信此转换可能有用:

应用于提供的源xml文档时:

最可能的结果是:


您可能希望在问题中显示您的预期输出,但我认为您只需要替换为并删除我在回答中对我的评论进行的扩展,以解释为什么会出现这种情况。谢谢这是想要的结果。你的答案和蒂姆的答案有什么不同?我认为唯一的问题是xpath。我们使用所谓的推式风格——不主动控制转换——例如via,但让XSLT处理模型为我们完成工作,并选择模板执行。虽然在Tim的回答中,他指定了他希望模板应用于哪些节点,但与此相反,在这个回答中,我们指定了哪些节点应该排除在XSLT处理模型的默认处理之外,例如。通常,推送样式提供了更大的灵活性,并且可以更紧凑
<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>
<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>