【问题标题】:xslt merge multiple nodes with same namexslt 合并多个同名节点
【发布时间】:2013-08-29 14:53:06
【问题描述】:

我可以看到许多类似问题的答案,但我似乎无法让它们为我工作。我有一些 xml 文件,其中一些兄弟元素节点具有相同的标签名称。我想使用 XSLT 合并这些节点。任何帮助将不胜感激。

输入:

<?xml version="1.0"?>
<Screen>
  <Shapes>
    <Triangle id="tri1">
    <color>red</color>
    <size>large</size>
    </Triangle>
  </Shapes>
  <Shapes>
    <Rectangle id="rec1">
      <color>blue</color>
      <size>medium</size>
    </Rectangle>
  </Shapes>
  <Shapes>
    <Circle id="cir1">
      <color>green</color>
      <size>small</size>
    </Circle>
  </Shapes>
  <Shapes>
    <Square id="sqr1">
      <color>yellow</color>
      <size>large</size>
    </Square>
  </Shapes>
  <Device>
    <Name>peg</Name>
    <type>X11</type>
  </Device>
  <Utilities>
    <Software>QT</Software>
    <Platform>Linux</Platform>
  </Utilities>
</Screen>

我想合并所有“形状”节点。 所需输出

<?xml version="1.0"?>
<Screen>
  <Shapes>
    <Triangle id="tri1">
      <color>red</color>
      <size>large</size>
    </Triangle>

    <Rectangle id="rec1">
      <color>blue</color>
      <size>medium</size>
    </Rectangle>

    <Circle id="cir1">
      <color>green</color>
      <size>small</size>
    </Circle>

    <Square id="sqr1">
      <color>yellow</color>
      <size>large</size>
    </Square>
  </Shapes>
  <Device>
    <Name>peg</Name>
    <type>X11</type>
  </Device>
  <Utilities>
    <Software>QT</Software>
    <Platform>Linux</Platform>
  </Utilities>
</Screen>

我试过的 XSLT 是:

<?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="Shapes">
    <xsl:if test="not(preceding-sibling::*[local-name() = 'Shapes'])">

      <Shapes>
        <xsl:apply-templates select="node() | @*" />
        <xsl:apply-templates select="following-sibling::*[local-name() = 'Shapes']" />
      </Shapes>
    </xsl:if>
    <xsl:if test="preceding-sibling::*[local-name() = 'Shapes']">
      <xsl:apply-templates select="node() | @*" />
    </xsl:if>
  </xsl:template>
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

但我得到的输出是 (:()

<Screen>
<Shapes>
    <Triangle id="tri1">
      <color>red</color>
      <size>large</size>
    </Triangle>

    <Rectangle id="rec1">
      <color>blue</color>
      <size>medium</size>
    </Rectangle>

    <Circle id="cir1">
      <color>green</color>
      <size>small</size>
    </Circle>

    <Square id="sqr1">
      <color>yellow</color>
      <size>large</size>
    </Square>
  </Shapes>

    <Rectangle id="rec1">
      <color>blue</color>
      <size>medium</size>
    </Rectangle>
    <Circle id="cir1">
      <color>green</color>
      <size>small</size>
    </Circle>
    <Square id="sqr1">
      <color>yellow</color>
      <size>large</size>
    </Square>

  <Device>
    <Name>peg</Name>
    <type>X11</type>
  </Device>
  <Utilities>
    <Software>QT</Software>
    <Platform>Linux</Platform>
  </Utilities>
</Screen>

是否有我可以使用的简单 XSLT 代码,或者我可以应用我的 xslt 中的任何修改来获取输出?

【问题讨论】:

    标签: xslt merge elements


    【解决方案1】:

    这应该可以完成工作:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
      <xsl:output method="xml" indent="yes"/>
    
      <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="/*">
        <xsl:copy>
          <Shapes>
            <xsl:copy-of select="Shapes/*"/>
          </Shapes>
          <xsl:apply-templates select="*[name()!='Shapes']"/>
        </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    

    思路是一次性将Shapes的所有子元素分别处理,然后复制剩下的。

    【讨论】:

    • 哇...答案比我在网上看到的任何其他潜在答案都简单而优雅,而且效果很好。不使用键/递归上一个或下一个兄弟调用。这真的很有帮助。非常感谢。 (还不能投票,因为我对这个网站还很陌生)
    • 谢谢,很高兴你喜欢它
    • 我尝试做同样的事情,但它复制了从源到输出的所有内容
    • 可能&lt;xsl:copy-of select="Shapes/*"/&gt; 不匹配任何内容 - 元素名称错误,或者源 XML 使用命名空间
    猜你喜欢
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多