Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 用xsl合并元素_Xml_Xslt_Merge - Fatal编程技术网

Xml 用xsl合并元素

Xml 用xsl合并元素,xml,xslt,merge,Xml,Xslt,Merge,我有多个xml元素,它们实际上引用同一个“对象”,它们可能有相同的数据,也可能有不同的数据。任何元素都可能有其他元素没有的元素。我希望xsl输出所有这些xml“对象”的元素之和。我们不会担心重叠。如何使用XSL进行这样的合并 例如: <root> <object> <property1>value</property1> </object> <object> <property1>value</proper

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

价值
价值
...
价值

此转换应用于sample.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>

价值
价值
价值
价值

尽管你以后可能想做得更好,但这应该会让你走得更远。

这可以通过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> 

1.
2.
3.
... 
4.
输出将是

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

3.
3.
4.

首先你说你想要所有元素的“和”,然后你说你不会被“重叠”所困扰。我觉得这是矛盾的。如果你有N/root/object/property1,你想要什么结果?如果有2个“property1”,我不担心会发生什么(现在),它可以是组合,第一个,也可以是最后一个。我现在不担心,因为需要编写更复杂的内容来处理这个问题。我先把“简单”的部分去掉。简单地说,我指的是没有冲突的部分。@aepeus。好的,XSLT是严格的要求吗?XSLT专家可能可以做到这一点,但我会选择一个类似DOM的库。谢谢,这可能也会很有帮助。