我得到了以下XML(由Excel电子表格中的某人生成)
<Records>
<record>
<Domain>Domain 1</Domain>
<Section>Section A</Section>
<label>Option X 1</label>
<Keyword>Unique KW 1</Keyword>
<Control>Checkbox</Control>
<Default>TRUE</Default>
</record>
<record>
<Domain>Domain 1</Domain>
<Section>Section B</Section>
<label>Option X 2</label>
<Keyword>Unique KW 2</Keyword>
<Control>Checkbox</Control>
<Default>TRUE</Default>
</record>
<record>
<Domain>Domain 2</Domain>
<Section>Section A</Section>
<label>Option X 3</label>
<Keyword>Unique KW 3</Keyword>
<Control>Checkbox</Control>
<Default>TRUE</Default>
</record>
<record>
<Domain>Domain 1</Domain>
<Section>Section A</Section>
<label>Option X 4</label>
<Keyword>Unique KW 4</Keyword>
<Control>Checkbox</Control>
<Default>FALSE</Default>
</record>
<record>
<Domain>Domain 1</Domain>
<Section>Section B</Section>
<label>Option X 5</label>
<Keyword>Unique KW 5</Keyword>
<Control>Checkbox</Control>
<Default>TRUE</Default>
</record>
<record>
<Domain>Domain 2</Domain>
<Section>Section B</Section>
<label>Option X 6</label>
<Keyword>Unique KW 6</Keyword>
<Control>Checkbox</Control>
<Default>TRUE</Default>
</record>
<record>
<Domain>Domain 1</Domain>
<Section>Section A</Section>
<label>Option X 7</label>
<Keyword>Unique KW 7</Keyword>
<Control>Checkbox</Control>
<Default>TRUE</Default>
</record>
</Records>
有人要求我使用XSLT 1.0将其转换为以下内容
<Configuration>
<Domain name="Domain 1">
<Section name="Section A">
<Option keyword="Unique KW 1" name="Option X 1">
<Control type="Checkbox" default="True" />
</Option>
<Option keyword="Unique KW 3" name="Option X 3">
<Control type="Checkbox" default="True" />
</Option>
<Option keyword="Unique KW 7" name="Option X 7">
<Control type="Checkbox" default="True" />
</Option>
</Section>
<Section name="Section B">
<Option keyword="Unique KW 2" name="Option X 2">
<Control type="Checkbox" default="True" />
</Option>
<Option keyword="Unique KW 5" name="Option X 5">
<Control type="Checkbox" default="True" />
</Option>
</Section>
</Domain>
<Domain name="Domain 2">
<Section name="Section A">
<Option keyword="Unique KW 3" name="Option X 3">
<Control type="Checkbox" default="True" />
</Option>
</Section>
<Section name="Section B">
<Option keyword="Unique KW 6" name="Option X 6">
<Control type="Checkbox" default="True" />
</Option>
</Section>
</Domain>
</Configuration>
过去,我使用XSLT的能力有限,但是我一直在努力获取单个元素(例如Domain和Section),我得到的输出是源中每个元素一个,其中每个值需要1个来源(如果有意义)。我似乎得到了很多
与该部分相同,而不仅仅是两个域(域1和域2)
使用XSLT 1.0可以做到这一点吗?还是我只是在浪费时间?
(此外,我提供的数据是一个示例,已进行了编辑以删除敏感数据和大小,还有更多的Domains和Section等)
(到目前为止我所获得的全部)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:dt="urn:schemas-microsoft-com:datatypes">
<xsl:output media-type="xml" indent="yes" />
<xsl:template match="/Records">
<Configuration>
<xsl:for-each select="record/Domain">
<Domain name="{text()}">
<Section name="{../Section/text()}">
<Option keyword="{../Keyword/text()}">
<Control type="{../Control/text()}"/>
</Option>
</Section>
</Domain>
</xsl:for-each>
</Configuration>
</xsl:template>
</xsl:stylesheet>
编辑: 看完Michaels的链接后(谢谢),我越来越近了。外部组(域)正在工作,但内部组没有工作
<xsl:key name="domain-name" match="record" use="Domain" />
<xsl:key name="section-name" match="record" use="Section" />
<xsl:template match="/Records">
<Configuration>
<xsl:for-each select="record[count(. | key('domain-name', Domain)[1]) = 1]">
<xsl:sort select="Domain" />
<Domain name="{Domain}">
<xsl:for-each select="record[count(. | key('section-name', Section)[1]) = 1]">
<xsl:sort select="Section" />
<Section name="{Section}">
<Option keyword="{Keyword/text()}">
<Control type="{Control/text()}"/>
</Option>
</Section>
</xsl:for-each>
</Domain>
</xsl:for-each>
</Configuration>
</xsl:template>
在给我
<Configuration>
<Domain name="Domain 1" />
<Domain name="Domain 2" />
</Configuration>
答案 0 :(得分:0)
对于内部分组,您将Section
中的Domain
个元素分组,因此两个元素都必须在键内
<xsl:key name="section-name" match="record" use="concat(Domain, '|', Section)" />
然后需要更改内部xsl:for-each
以使用新的密钥格式。而且还因为您正在执行xsl:for-each select="group...."
而无法工作,因为您当前位于record
上,因此内部xsl:for-each
正在寻找也称为record
的子元素。看起来应该像这样,它仅将record
元素用作当前Domain
的值
<xsl:for-each select="key('domain-name', Domain)[count(. | key('section-name', concat(Domain, '|', Section))[1]) = 1]">
尝试使用此XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="domain-name" match="record" use="Domain" />
<xsl:key name="section-name" match="record" use="concat(Domain, '|', Section)" />
<xsl:template match="/Records">
<Configuration>
<xsl:for-each select="record[count(. | key('domain-name', Domain)[1]) = 1]">
<xsl:sort select="Domain" />
<Domain name="{Domain}">
<xsl:for-each select="key('domain-name', Domain)[count(. | key('section-name', concat(Domain, '|', Section))[1]) = 1]">
<xsl:sort select="Section" />
<Section name="{Section}">
<Option keyword="{Keyword/text()}">
<Control type="{Control/text()}"/>
</Option>
</Section>
</xsl:for-each>
</Domain>
</xsl:for-each>
</Configuration>
</xsl:template>
</xsl:stylesheet>
看起来您还需要在Keyword
上进行第三级分组,但是您现在应该可以解决此问题(您需要使用密钥来考虑Domain
,{{1 }}和Section
)