我很难编写一个XSLT来将具有相同属性值的所有节点移动到同一级别。
以下是一个例子:
<root>
<object Name="1">
<Property Name="a1" Value="a">
<Property Name="a1.1" Value="a"/>
<Property Name="a1.2" Value="a">
<Property Name="a1.2.1" Value="a"/>
<Property Name="a1.2.2" Value="a"/>
</Property>
</Property>
<Property Name="b1" Value="b"/>
</object>
</root>
目前,可以将值为a的属性嵌套在另一个内部(节点数量或嵌套级别没有限制)。此模型将更改为仅在对象级别允许此类型的属性。 转换后应该是这样的(元素的顺序无关紧要):
<root>
<object Name="1">
<Property Name="a1" Value="a"/>
<Property Name="a1.1" Value="a"/>
<Property Name="a1.2" Value="a">
<Property Name="a1.2.1" Value="a"/>
<Property Name="a1.2.2" Value="a"/>
<Property Name="b1" Value="b"/>
</object>
</root>
我尝试用this very similar question解决这个问题,主要区别在于示例中不会复制节点,但会使用其值。我一直无法弄清楚如何复制整个节点。
修改
上面的例子过于简化了。属性将包含必须复制的子元素
<root>
<object Name="1">
<Property Name="a1" Value="a">
<x>x1</x>
<y>y1</y>
<z>z1</z>
<Property Name="a1.1" Value="a">
<x>x1.1</x>
<y>y1.1</y>
<z>z1.1</z>
</Property>
<Property Name="a1.2" Value="a">
<x>x1.2</x>
<y>y1.2</y>
<z>z1.2</z>
<Property Name="a1.2.1" Value="a">
<x>x1.2.1</x>
<y>y1.2.1</y>
<z>z1.2.1</z>
</Property>
<Property Name="a1.2.2" Value="a">
<x>x1.2.1</x>
<y>y1.2.1</y>
<z>z1.2.1</z>
</Property>
</Property>
</Property>
<Property Name="b1" Value="b"/>
</object>
</root>
转型后应该成为这个:
<root>
<object Name="1">
<Property Name="a1" Value="a">
<x>x1</x>
<y>y1</y>
<z>z1</z>
</Property>
<Property Name="a1.1" Value="a">
<x>x1.1</x>
<y>y1.1</y>
<z>z1.1</z>
</Property>
<Property Name="a1.2" Value="a">
<x>x1.2</x>
<y>y1.2</y>
<z>z1.2</z>
</Property>
<Property Name="a1.2.1" Value="a">
<x>x1.2.1</x>
<y>y1.2.1</y>
<z>z1.2.1</z>
</Property>
<Property Name="a1.2.2" Value="a">
<x>x1.2.1</x>
<y>y1.2.1</y>
<z>z1.2.1</z>
</Property>
<Property Name="b1" Value="b"/>
</object>
</root>
答案 0 :(得分:2)
如果你从XSLT identity template开始,你需要的只是另一个匹配Property
的模板,它复制元素和属性,但输出元素之后的子元素,而不是元素。
<xsl:template match="Property">
<xsl:copy>
<xsl:apply-templates select="@*"/>
</xsl:copy>
<xsl:apply-templates select="node()" />
</xsl:template>
试试这个XSLT
<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="Property">
<xsl:copy>
<xsl:apply-templates select="@*"/>
</xsl:copy>
<xsl:apply-templates select="node()" />
</xsl:template>
</xsl:stylesheet>
请注意,我假设Property
个元素在此处只能包含其他Property
个元素。
答案 1 :(得分:1)
重新编辑您的问题 - 请尝试以下方式:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Property">
<xsl:copy>
<xsl:apply-templates select="@*|node()[not(self::Property)]"/>
</xsl:copy>
<xsl:apply-templates select="Property" />
</xsl:template>
</xsl:stylesheet>