首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >xslt根据拆分和父节点名生成子节点

xslt根据拆分和父节点名生成子节点
EN

Stack Overflow用户
提问于 2011-02-04 01:41:32
回答 4查看 1.2K关注 0票数 2

是否可以在xsl中执行以下操作。我正在尝试拆分元素的内容,并基于拆分创建子元素。让事情变得更复杂的是,偶尔会出现异常(即节点4不会被拆分)。我想知道是否有一种方法可以在不为每个元素硬编码显式拆分的情况下做到这一点。再说一次,不确定这是否可能。谢谢你的帮助!

原始XML:

代码语言:javascript
复制
<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

代码语言:javascript
复制
<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>
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-02-04 02:31:09

这是一个XSL 1.0解决方案。我假设您的示例输出中的node-4中的不一致只是一个打字错误。否则,您将不得不定义为什么node3被拆分而node4没有被拆分。

代码语言:javascript
复制
<?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下的同一级别,此操作就有效。如果实际文档结构不同,则必须调整解决方案以与之匹配。

票数 1
EN

Stack Overflow用户

发布于 2011-02-04 04:29:04

为了让事情变得更复杂,偶尔会有例外(即节点4不会被拆分)。我想知道是否有一种方法可以在不为每个元素硬编码显式拆分的情况下做到这一点。

模式匹配文本节点要标记化,这是一个更具语义的样式表:

代码语言:javascript
复制
<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>

输出:

代码语言:javascript
复制
<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文本节点)。

票数 2
EN

Stack Overflow用户

发布于 2011-02-04 01:48:12

您能使用XSLT 2.0吗?如果是这样的话,听起来正合你的胃口。您可以基于regexp拆分。

如果你需要更多的细节,可以问...

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4889594

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档