<Rootnode>
<Properties Attribute ="xxx">
<Type>1</Type>
<Size>10</Size>
</Properties>
<Other>
<blah>h</blah>
</Other>
<Other2>
<blah>h</blah>
</Other2>
<Properties Attribute ="xxx">
<xType>5</xType>
<xSize>10</xSize>
</Properties>
<Items>
<Item4>8</Item4>
</Items>
<Items>
<Item6>8</Item6>
</Items>
<Properties Attribute ="xxx">
<zType>1</zType>
<zSize>10</zSize>
</Properties>
<Items place="UK">
<Item1>8</Item1>
</Items>
</Rootnode>
现在我想要的只是包含属性和项目。如果属性具有相同的名称和值,则最好将Properties和Items组连接在一起,并根据Attributes SORT Properties和Items,并按字母顺序对子节点进行排序。 到目前为止,我已经空白了;(
所需的输出几乎与ABach所示相同。虽然我忘了提到的一件事是每个属性或项目上可能有其他属性,我知道我想要排序的属性的名称。我可以很容易地修改。
即所需的输出
<?xml version="1.0"?>
<Rootnode>
<Properties Attribute="xxx">
<Size>10</Size>
<Type>1</Type>
<xSize>10</xSize>
<xType>5</xType>
<zSize>10</zSize>
<zType>1</zType>
</Properties>
<Items>
<Item4>8</Item4>
<Item6>8</Item6>
</Items>
<Items place="UK">
<Item1>8</Item1>
</Items>
</Rootnode>
对于到目前为止我没有努力而道歉...我最终陷入了混乱,并且认为它不会有太多帮助......我对这些东西很新:)
答案 0 :(得分:2)
正如@LarsH已经指出的那样,通过不向我们展示预期的输出XML,我们只能猜测你真正想要的东西。也就是说,这是我尝试使用XSLT 1.0解决方案。
当这个XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output omit-xml-declaration="no" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key
name="PropertiesByAttributeNameVal"
match="Properties"
use="concat(name(@*[1]), '+', @*[1])" />
<xsl:key
name="ItemsByAttributeNameVal"
match="Items"
use="concat(name(@*[1]), '+', @*[1])" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="Rootnode">
<Rootnode>
<xsl:apply-templates
select="Properties[
generate-id() =
generate-id(key(
'PropertiesByAttributeNameVal',
concat(name(@*[1]), '+', @*[1]))[1])]">
<xsl:with-param name="pKeyName"
select="'PropertiesByAttributeNameVal'" />
<xsl:sort select="concat(name(@*[1]), '+', @*[1])" />
</xsl:apply-templates>
<xsl:apply-templates
select="Items[
generate-id() =
generate-id(key(
'ItemsByAttributeNameVal',
concat(name(@*[1]), '+', @*[1]))[1])]">
<xsl:with-param name="pKeyName"
select="'ItemsByAttributeNameVal'" />
<xsl:sort select="concat(name(@*[1]), '+', @*[1])" />
</xsl:apply-templates>
</Rootnode>
</xsl:template>
<xsl:template match="Properties|Items">
<xsl:param name="pKeyName" />
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates
select="key($pKeyName, concat(name(@*[1]), '+', @*[1]))/*">
<xsl:sort select="name()" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
...针对提供的XML运行:
<Rootnode>
<Properties Attribute="xxx">
<Type>1</Type>
<Size>10</Size>
</Properties>
<Other>
<blah>h</blah>
</Other>
<Other2>
<blah>h</blah>
</Other2>
<Properties Attribute="xxx">
<xType>5</xType>
<xSize>10</xSize>
</Properties>
<Items>
<Item4>8</Item4>
</Items>
<Items>
<Item6>8</Item6>
</Items>
<Properties Attribute="xxx">
<zType>1</zType>
<zSize>10</zSize>
</Properties>
<Items place="UK">
<Item1>8</Item1>
</Items>
</Rootnode>
...我猜是正确的输出XML是生成的:
<?xml version="1.0"?>
<Rootnode>
<Properties Attribute="xxx">
<Size>10</Size>
<Type>1</Type>
<xSize>10</xSize>
<xType>5</xType>
<zSize>10</zSize>
<zType>1</zType>
</Properties>
<Items>
<Item4>8</Item4>
<Item6>8</Item6>
</Items>
<Items place="UK">
<Item1>8</Item1>
</Items>
</Rootnode>
请注意,如果针对略微修改的XML文档(具有更多分组等)运行相同的XSLT:
<?xml version="1.0" encoding="utf-8"?>
<Rootnode>
<Properties Attribute="xxx">
<Type>1</Type>
<Size>10</Size>
</Properties>
<Other>
<blah>h</blah>
</Other>
<Other2>
<blah>h</blah>
</Other2>
<Properties Attribute="yyy">
<xType>5</xType>
<xSize>10</xSize>
</Properties>
<Items>
<Item4>8</Item4>
</Items>
<Items place="US">
<Item9>8</Item9>
</Items>
<Items>
<Item1>8</Item1>
</Items>
<Properties Attribute2="xxx">
<zType>1</zType>
<zSize>10</zSize>
</Properties>
<Properties Attribute="xxx">
<elephantType>5</elephantType>
<elephantSize>15</elephantSize>
</Properties>
<Items place="UK">
<Item1>8</Item1>
</Items>
</Rootnode>
...再次,我假设正确答案产生了:
<?xml version="1.0"?>
<Rootnode>
<Properties Attribute="xxx">
<Size>10</Size>
<Type>1</Type>
<elephantSize>15</elephantSize>
<elephantType>5</elephantType>
</Properties>
<Properties Attribute="yyy">
<xSize>10</xSize>
<xType>5</xType>
</Properties>
<Properties Attribute2="xxx">
<zSize>10</zSize>
<zType>1</zType>
</Properties>
<Items>
<Item1>8</Item1>
<Item4>8</Item4>
</Items>
<Items place="UK">
<Item1>8</Item1>
</Items>
<Items place="US">
<Item9>8</Item9>
</Items>
</Rootnode>
<强>假设:强>
<Properties>
和<Items>
元素只有一个属性,它应该是分组限定符。<强>解释强>
因为这是一个XSLT 1.0解决方案,Muenchian Grouping
是在唯一选择器下对节点和属性进行分组时的顺序。因此,我们定义了两个键:一个用于<Properties>
元素,另一个用于<Items>
元素。
第一个模板是Identity Transform
- 它的工作是按原样将源文档中的所有节点和属性输出到结果文档。
第二个模板与<Rootnode>
元素匹配。系统会指示仅将模板应用于首先出现在各自键中的<Properties>
和<Items>
元素;这具有仅处理唯一元素的预期效果(基于其第一个属性的名称和值)。
当指定<xsl:apply-templates>
元素时,请注意在两个实例中,都指示按相同的属性名称/值配对对结果进行排序。
请注意,每个<xsl:apply-templates>
元素都有一个参数(通过<xsl:with-param>
)。如您所见,处理<Properties>
和<Items>
元素的代码几乎相同;唯一的区别是我们从中获取结果的关键。因此,我选择将该逻辑合并到第三个模板中,并通过此参数考虑可变性。
第三个模板与<Properties>
和<Items>
元素相匹配。对于每个,复制原始节点(其属性也是如此)。最后,模板应用于此元素的所有子元素(发生适当的排序[此次,基于子元素本身的名称])。
答案 1 :(得分:1)
如果你已经拥有某些东西而不是什么,那么你将更有可能获得帮助。首先,创建一个与属性和项目(match="Properties | Items"
)匹配的模板,其内容只复制匹配的元素:<xsl:copy-of select="." />
。
这将为您提供一些可用的代码。
我建议的下一步是发布所需输出的样本,以及XSLT代码给出的实际输出。
这将为人们回答你的问题提供一个更小的差距。