【问题标题】:merging elements with xsl用 xsl 合并元素
【发布时间】:2011-10-06 20:40:32
【问题描述】:

我有多个实际引用同一个“对象”的 xml 元素,它们可能具有相同的数据,也可能具有不同的数据。任何人都可能有其他人没有的元素。我希望我的 xsl 输出所有这些 xml“对象”的元素的总和。我们不会担心重叠。如何使用 XSL 进行这样的合并?

例子:

<root>
<object>
<property1>value</property1>
</object>
<object>
<property1>value</property1>
<property2>value</property2>
</object>
...
<object>
<propertyN>value</propertyN>
</object>
</root>

结果:

<root>
<object>
<property1>value</property1>
<property2>value</property2>
...
<propertyN>value</propertyN>
</object>
</root>

【问题讨论】:

  • 首先你说你想要所有元素的“总和”,然后你说你不会被“重叠”所困扰。我觉得这很矛盾。如果你有 N 个 /root/object/property1,你想要什么结果?
  • 如果有 2 个“property1”,我不担心那里(还)有什么,它可以是组合,第一个或最后一个。我现在不担心它,因为必须编写更复杂的东西来处理它。我先把“简单”的部分排除在外。简单来说,我的意思是没有冲突的部分。
  • @aepeus。好的,XSLT 是严格要求吗? XSLT 大师可能可以做到这一点,但我会选择类似 DOM 的库。

标签: xml xslt merge


【解决方案1】:

此转换应用于您的示例 .xml

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"      xmlns:ext="www.foo.com">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
<root>
  <object>
    <xsl:for-each select="/root/object//*">
      <xsl:copy-of select="."/>
    </xsl:for-each>
  </object>
</root>
</xsl:template>
</xsl:stylesheet>

产生这个输出:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<object>
  <property1>value</property1>
  <property1>value</property1>
  <property2>value</property2>
  <propertyN>value</propertyN>
</object>
</root>

虽然你以后可能想做得更好,但这应该会让你继续前进。

【讨论】:

    【解决方案2】:

    这可以通过 Meunchian 分组来实现。

    首先定义一个键来匹配 property 元素(在这种情况下,我假设 object 的所有子节点都是属性),使用名称作为外观-起来。

    接下来,您需要匹配每个属性名称的第一次出现,通过检查它是查找键中的第一个此类属性

    <xsl:apply-templates 
     select="//object/*[generate-id() = generate-id(key('property', local-name())[1])]" />
    

    然后您可以简单地复制这些匹配项。

    这是完整的 XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       <xsl:output method="xml" indent="yes"/>
    
       <xsl:key name="property" match="object/*" use="local-name()"/>
    
       <xsl:template match="/">
          <object>
             <xsl:apply-templates select="//object/*[generate-id() = generate-id(key('property', local-name())[1])]"/>
          </object>
       </xsl:template>
    
       <xsl:template match="*">
          <xsl:copy-of select="."/>
       </xsl:template>
    
    </xsl:stylesheet>
    

    当应用于您的示例 XML 时,输出如下:

    <object>
    <property1>value</property1>
    <property2>value</property2>
    <propertyN>value</propertyN>
    </object>
    

    在这种情况下,仅返回第一次出现的属性名称。如果你想组合元素,你可以例如(假设值都是数字),对它们求和

    <xsl:template match="*">
      <xsl:copy>
        <xsl:value-of select="sum(key('property', local-name()))" />
      </xsl:copy>
    </xsl:template>
    

    所以,给定这个输入 XML....

    <root> 
    <object> 
    <property1>1</property1> 
    </object> 
    <object> 
    <property1>2</property1> 
    <property2>3</property2> 
    </object> 
    ... 
    <object> 
    <propertyN>4</propertyN> 
    </object> 
    </root> 
    

    输出将是......

    <object>
    <property1>3</property1>
    <property2>3</property2>
    <propertyN>4</propertyN>
    </object>
    

    【讨论】:

    • 谢谢,这可能也会有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 2021-12-11
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多