是否可以在xsl中执行以下操作。我正在尝试拆分元素的内容,并基于拆分创建子元素。让事情变得更复杂的是,偶尔会出现异常(即节点4不会被拆分)。我想知道是否有一种方法可以在不为每个元素硬编码显式拆分的情况下做到这一点。再说一次,不确定这是否可能。谢谢你的帮助!
原始XML:
<document>
<node>
<node-1>hello world1</node-1>
<node-2>hello^world2</node-2>
<node-3>hello^world3</node-3>
<node-4>hello^world4</node-4>
</node>
</document>转换后的XML
<document>
<node>
<node-1>hello world1</node-1>
<node-2>
<node2-1>hello</node2-1>
<node2-2>world2</node2-2>
</node-2>
<node-3>
<node3-1>hello</node3-1>
<node3-2>world3</node3-2>
</node-3>
<node-4>hello^world4</node-4>
</node>
</document>发布于 2011-02-04 02:31:09
这是一个XSL 1.0解决方案。我假设您的示例输出中的node-4中的不一致只是一个打字错误。否则,您将不得不定义为什么node3被拆分而node4没有被拆分。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<document>
<node>
<xsl:apply-templates select="document/node/*"/>
</node>
</document>
</xsl:template>
<xsl:template match="*">
<xsl:variable name="tag" select="name()"/>
<xsl:choose>
<xsl:when test="contains(text(),'^')">
<xsl:element name="{$tag}">
<xsl:element name="{concat($tag,'-1')}">
<xsl:value-of select="substring-before(text(),'^')"/>
</xsl:element>
<xsl:element name="{concat($tag,'-2')}">
<xsl:value-of select="substring-after(text(),'^')"/>
</xsl:element>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>只要要拆分的所有节点都在/document/node下的同一级别,此操作就有效。如果实际文档结构不同,则必须调整解决方案以与之匹配。
发布于 2011-02-04 04:29:04
为了让事情变得更复杂,偶尔会有例外(即节点4不会被拆分)。我想知道是否有一种方法可以在不为每个元素硬编码显式拆分的情况下做到这一点。
模式匹配文本节点要标记化,这是一个更具语义的样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()[contains(.,'^')]" name="tokenize">
<xsl:param name="pString" select="concat(.,'^')"/>
<xsl:param name="pCount" select="1"/>
<xsl:if test="$pString">
<xsl:element name="{translate(name(..),'-','')}-{$pCount}">
<xsl:value-of select="substring-before($pString,'^')"/>
</xsl:element>
<xsl:call-template name="tokenize">
<xsl:with-param name="pString"
select="substring-after($pString,'^')"/>
<xsl:with-param name="pCount" select="$pCount + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="node-4/text()">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>输出:
<document>
<node>
<node-1>hello world1</node-1>
<node-2>
<node2-1>hello</node2-1>
<node2-2>world2</node2-2>
</node-2>
<node-3>
<node3-1>hello</node3-1>
<node3-2>world3</node3-2>
</node-3>
<node-4>hello^world4</node-4>
</node>
</document>注释:一个经典的记号赋予器(实际上,它使用了一个规范化的字符串,允许顺序中的空项)。模式匹配和覆盖规则(保留node-4文本节点)。
发布于 2011-02-04 01:48:12
您能使用XSLT 2.0吗?如果是这样的话,听起来正合你的胃口。您可以基于regexp拆分。
如果你需要更多的细节,可以问...
https://stackoverflow.com/questions/4889594
复制相似问题