首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSLT XML到XML的转换,同时替换和重新排列节点

XSLT XML到XML的转换,同时替换和重新排列节点
EN

Stack Overflow用户
提问于 2017-12-23 21:55:56
回答 1查看 27关注 0票数 0

我有一个很大的XML文件,它的结构如下:

代码语言:javascript
复制
<text n="1">
    <front>
      <title n="t1-1">A</title>
      <title n="t1-2">B</title>
    </front>
    <body>
      <p>
        <seg n="1-1">some <add>foo</add> text</seg>
        <seg n="1-2">some <add>foo</add>  <add>foo</add> text</seg>
        <seg n="1-3">some <add>foo</add> text</seg>
      </p>
    </body>
</text>
<text n="2">
    <front>
      <title n="t2-1">X</title>
      <title n="t2-2">Y</title>
    </front>
    <body>
      <p>
        <seg n="2-1">some <add>foo</add> text</seg>
        <seg n="2-2">some <add>foo</add> text</seg>
        <seg n="2-3">some text</seg>
      </p>
    </body>
</text>
<text>
  .....
</text>

我想把它转换成一个新的XML文档,结构如下:

代码语言:javascript
复制
<document>
   <p n="1">
     <newtitle>A B</title>
     <seg n="1-1">some text</seg>
     <seg n="1-2">some text</seg>
     <seg n="1-3">some text</seg>
     <adds>
          <add>foo</add>
          <add>foo</add>
          <add>foo</add>
          <add>foo</add>
      </adds>
   </p>
   <p n="2">
      <newtitle>X Y</title>
      <seg n="2-1">some text</seg>
      <seg n="2-2">some text</seg>
      <seg n="2-3">some text</seg>
      <adds>
          <add>foo</add>
          <add>foo</add>
      </adds>
   </p>
   <p>
   ....
   </p>
</document>

我尝试了几次在xsl:for-each中使用identity transform,但都不能正确地提取和重新排列。

提前感谢您的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-23 22:22:31

下面是一个XSLT3解决方案(对于XSLT2,您需要用标识转换模板拼写<xsl:mode on-no-match="shallow-copy"/> ):

代码语言:javascript
复制
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:template match="root">
      <document>
          <xsl:apply-templates/>
      </document>
  </xsl:template>

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

  <xsl:template match="text/front">
      <newtitle>
          <xsl:value-of select="title"/>
      </newtitle>
  </xsl:template>

  <xsl:template match="text/body">
      <xsl:apply-templates select="p/seg"/>
      <adds>
          <xsl:apply-templates select="p/seg/add"/>
      </adds>
  </xsl:template>

  <xsl:template match="text/body/p/seg">
      <xsl:copy>
          <xsl:apply-templates select="@* | text()"/>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

正如您所看到的,通过将任务分解为模板以将每个节点转换为其目标,您将获得一种结构良好的方法。

http://xsltfiddle.liberty-development.net/nbUY4kh/2上的在线示例

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

https://stackoverflow.com/questions/47953086

复制
相关文章

相似问题

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