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

时间:2019-06-28 11:44:57

标签: xml xslt xslt-1.0

我是XML和XSLT的新手。我试图用XML分隔XML文件中的特定节点。我已经看到了执行此操作的代码,并尝试将其合并到XSLT文件中。它可以工作,但是输出包含所有节点,并且忽略了我希望的路径。 这是我的XML文件:

npm i firebase-tools@7.0.0 -g  

这是我的XSLT文件。

<?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来创建输出文件,并且如果节点包含逗号,它将在输出中将它们分开?

2 个答案:

答案 0 :(得分:2)

当您执行<xsl:apply-templates select="hero" />时,请选择hero下的所有子fortnight元素,然后XSLT寻找要应用于它们的模板。但是,您的XSLT中没有匹配hero的模板。发生这种情况时,将应用XSLT的built-in template rules。在这种情况下,将应用以下模板

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

因此,有效地,它将选择XML中的所有内容,直到到达文本节点为止。不仅是characters下的文本节点,还包括所有文本节点。

您需要做的是仅将要拆分的节点作为目标。这意味着将<xsl:apply-templates select="hero" />替换为<xsl:apply-templates select="hero/characters" />

还要注意,<xsl:value-of select="characters" />行可以删除。因为这是在匹配fortnight的模板中,所以只会选择characters的直接子元素fortnight,而这些元素都不存在。

答案 1 :(得分:0)

尽管您没有向我们展示转换所需的结果,但我相信此转换可能有用

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