XSLT 复制所有节点,并在分隔符上拆分 [英] XSLT to copy over all nodes, and split on delimiter
本文介绍了XSLT 复制所有节点,并在分隔符上拆分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在寻找执行以下操作的 xslt:
I'm looking for an xslt that does the following:
以输入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.我不知道所有节点是什么,即我不知道我正在接收一个 foo1
节点,我只想直接复制它们.不过,对于某些节点,我确实知道它们是什么,我想用分隔符将它们分开并相应地编号,如下所示.
I want to copy all of the existing nodes to the resultant xml. I won't know what all the nodes are, i.e. I won't know that I'm receiving a foo1
node, I just want to copy them over directly. For certain nodes though, I do know what they are and I want to split them by a delimiter and number them accordingly, as below.
<?xml version="1.0" encoding="UTF-8"?>
<root>
<foo1>bar1</foo1>
<foo2>
<foo2-1>bar2</foo2-1>
<foo2-2>bar3</food2-2>
<foo2-3>bar4</foo2-3>
</foo2>
<foo3>
<foo3-1>bar3</foo3-1>
<foo3-2>bar3</food2-2>
</foo3>
<unknown>more data</unknown>
</root>
任何帮助将不胜感激.
谢谢.
推荐答案
这在 XSLT 2.0 中很容易做到:
This is fairly easy to do in 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>
<小时>
在 XSLT 1.0 中,您需要使用递归模板调用.例如:
In XSLT 1.0 you would need to use a recursive template call. For example:
<?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 复制所有节点,并在分隔符上拆分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文