使用xsl合并元素

时间:2011-10-06 20:40:33

标签: xml xslt merge

我有多个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>

2 个答案:

答案 0 :(得分: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>

虽然您可能希望以后做些更好的事情,但这应该可以帮到您。

答案 1 :(得分:1)

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

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

接下来,您需要匹配每个属性名称的第一个匹配项,方法是检查它是查找键中的第一个此类属性

<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>