Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用xslt将字符串以分号分隔为xml元素_Xml_Xslt_Xslt 1.0 - Fatal编程技术网

使用xslt将字符串以分号分隔为xml元素

使用xslt将字符串以分号分隔为xml元素,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我已经转换了xml: <import> <issue> <article> <languageVersion> <title>some title</title> <keywords>keyword1; keyword2; keyword3</keywords> &l

我已经转换了xml:

<import>
    <issue>
        <article>
            <languageVersion>
                <title>some title</title>
                <keywords>keyword1; keyword2; keyword3</keywords>
            </languageVersion>
        </article>
        <article>
            <languageVersion>
                <title>some title</title>
                <keywords>keyword1; keyword2; keyword3</keywords>
            </languageVersion>
        </article>
    </issue>
</import>

但不幸的是,代码正在破坏其余的xml元素:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="keywords">
        <keywords>
            <xsl:apply-templates/>
        </keywords>
    </xsl:template>
    <xsl:template match="keywords" name="split">
        <xsl:param name="pText" select="."/>
        <xsl:param name="pItemElementName" select="'keyword'"/>
        <xsl:if test="string-length($pText) > 0">
            <xsl:variable name="vNextItem" select=
      "substring-before(concat($pText, ';'), ';')"/>
            <xsl:element name="{$pItemElementName}">
                <xsl:value-of select="$vNextItem"/>
            </xsl:element>
            <xsl:call-template name="split">
                <xsl:with-param name="pText" select="substring-after($pText, ';')"/>
                <xsl:with-param name="pItemElementName" select="$pItemElementName"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

您有两个模板匹配
关键字
,如果它们具有相同的优先级,则在XSLT中被视为错误。根据规范

XSLT处理器可能会发出错误信号;如果它没有发出信号 错误,必须从匹配模板中选择恢复 剩下的规则,即样式表中最后出现的规则

因此,在您的例子中,只使用了第二个模板

但是,您只需删除第二个模板上的“匹配项”,使其成为命名模板,然后更改第一个模板以直接调用命名模板。您还应该添加标识模板,以处理现有元素,然后您的工作就完成了

试试这个XSLT

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="keywords">
        <xsl:copy>
            <xsl:call-template name="split" />
        </xsl:copy>
    </xsl:template>

    <xsl:template name="split">
        <xsl:param name="pText" select="."/>
        <xsl:param name="pItemElementName" select="'keyword'"/>
        <xsl:if test="string-length($pText) > 0">
            <xsl:variable name="vNextItem" select=
      "substring-before(concat($pText, ';'), ';')"/>
            <xsl:element name="{$pItemElementName}">
                <xsl:value-of select="$vNextItem"/>
            </xsl:element>
            <xsl:call-template name="split">
                <xsl:with-param name="pText" select="substring-after($pText, ';')"/>
                <xsl:with-param name="pItemElementName" select="$pItemElementName"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>


这几乎完美无瑕,但它并不是在元素之间创建节点,我应该做些什么来获得它?我已经修改了我的答案来做到这一点。现在效果非常好,我批准了答案。除此之外,还可以从所有关键字中删除空格?因此,它将取代关键字2。是的,您可以使用
规范化空间
函数,因此您将执行
是的,这就是我所说的。谢谢
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="keywords">
        <xsl:copy>
            <xsl:call-template name="split" />
        </xsl:copy>
    </xsl:template>

    <xsl:template name="split">
        <xsl:param name="pText" select="."/>
        <xsl:param name="pItemElementName" select="'keyword'"/>
        <xsl:if test="string-length($pText) > 0">
            <xsl:variable name="vNextItem" select=
      "substring-before(concat($pText, ';'), ';')"/>
            <xsl:element name="{$pItemElementName}">
                <xsl:value-of select="$vNextItem"/>
            </xsl:element>
            <xsl:call-template name="split">
                <xsl:with-param name="pText" select="substring-after($pText, ';')"/>
                <xsl:with-param name="pItemElementName" select="$pItemElementName"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>