Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.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
Xml XSLT在所有节点上复制,并在分隔符上拆分_Xml_Xslt - Fatal编程技术网

Xml XSLT在所有节点上复制,并在分隔符上拆分

Xml XSLT在所有节点上复制,并在分隔符上拆分,xml,xslt,Xml,Xslt,我正在寻找一种xslt,它可以实现以下功能: 使用的输入xml,例如: <?xml version="1.0" encoding="UTF-8"?> <root> <foo1>bar1</foo1> <foo2>bar2^bar3^bar4</foo2> <foo3>bar3^bar3</foo3> <unknown>more data</unknow

我正在寻找一种xslt,它可以实现以下功能:

使用的输入xml,例如:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <foo1>bar1</foo1>
    <foo2>bar2^bar3^bar4</foo2>
    <foo3>bar3^bar3</foo3>
    <unknown>more data</unknown>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>

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

<xsl:template match="text()[contains(.,'^')]">  
    <xsl:variable name="elementName" select="name(..)"/>

    <xsl:call-template name="splitIntoElements">
        <xsl:with-param name="baseName" select="name(..)" />
        <xsl:with-param name="txt" select="." />    
    </xsl:call-template>

</xsl:template>

<xsl:template name="splitIntoElements">
    <xsl:param name="baseName" />
    <xsl:param name="txt" />
    <xsl:param name="delimiter" select="'^'" />
    <xsl:param name="index" select="1" />

    <xsl:variable name="first" select="substring-before($txt, $delimiter)" />
    <xsl:variable name="remaining" select="substring-after($txt, $delimiter)" />

    <xsl:element name="{$baseName}-{$index}">
        <xsl:choose>
            <xsl:when test="$first">
                <xsl:value-of select="$first" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$txt" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:element>

    <xsl:if test="$remaining">
        <xsl:call-template name="splitIntoElements">
            <xsl:with-param name="baseName" select="$baseName" />
            <xsl:with-param name="txt" select="$remaining" />
            <xsl:with-param name="index" select="$index+1" />
            <xsl:with-param name="delimiter" select="$delimiter" />
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>
任何帮助都将不胜感激


谢谢。

这在XSLT 2.0中相当容易做到:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output indent="yes"/>

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

<xsl:template match="text()[contains(.,'^')]">  
    <xsl:variable name="elementName" select="name(..)"/>
    <xsl:for-each select="tokenize(.,'\^')">
         <xsl:element name="{$elementName}-{position()}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:for-each>  
</xsl:template>

</xsl:stylesheet>


在XSLT1.0中,需要使用递归模板调用。例如:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <foo1>bar1</foo1>
    <foo2>bar2^bar3^bar4</foo2>
    <foo3>bar3^bar3</foo3>
    <unknown>more data</unknown>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>

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

<xsl:template match="text()[contains(.,'^')]">  
    <xsl:variable name="elementName" select="name(..)"/>

    <xsl:call-template name="splitIntoElements">
        <xsl:with-param name="baseName" select="name(..)" />
        <xsl:with-param name="txt" select="." />    
    </xsl:call-template>

</xsl:template>

<xsl:template name="splitIntoElements">
    <xsl:param name="baseName" />
    <xsl:param name="txt" />
    <xsl:param name="delimiter" select="'^'" />
    <xsl:param name="index" select="1" />

    <xsl:variable name="first" select="substring-before($txt, $delimiter)" />
    <xsl:variable name="remaining" select="substring-after($txt, $delimiter)" />

    <xsl:element name="{$baseName}-{$index}">
        <xsl:choose>
            <xsl:when test="$first">
                <xsl:value-of select="$first" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$txt" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:element>

    <xsl:if test="$remaining">
        <xsl:call-template name="splitIntoElements">
            <xsl:with-param name="baseName" select="$baseName" />
            <xsl:with-param name="txt" select="$remaining" />
            <xsl:with-param name="index" select="$index+1" />
            <xsl:with-param name="delimiter" select="$delimiter" />
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

很高兴听到这个消息。您使用的是1.0版还是2.0版?