我有这样的XML
<ContractInfo ContractNo="12345">
<Details LastName="Goodchild">
<Filedata FileName="File1"/>
</Details>
</ContractInfo>
<ContractInfo ContractNo="12345">
<Details LastName="Goodchild">
<Filedata FileName="File2"/>
</Details>
</ContractInfo>
<ContractInfo ContractNo="123456">
<Details LastName="Goodchild">
<Filedata FileName="File2"/>
</Details>
</ContractInfo>
Run Code Online (Sandbox Code Playgroud)
我希望我的输出XML是这样的
<ContractInfo ContractNo="12345">
<Details LastName="Goodchild">
<Filedata FileName="File1"/>
<Filedata FileName="File2"/>
</Details>
</ContractInfo>
<ContractInfo ContractNo="123456">
<Details LastName="Goodchild">
<Filedata FileName="File2"/>
</Details>
</ContractInfo>
Run Code Online (Sandbox Code Playgroud)
这里,需要在输出中组合与匹配"contractNo"有关的'FileData'.可以使用XSLT实现这种转换吗?
提前致谢.
作者Srini
以下XSLT 1.0转换产生了正确的结果:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:key name="contract" match="ContractInfo" use="@ContractNo" />
<xsl:key name="filedata" match="Filedata" use="../../@ContractNo" />
<xsl:template match="ContractInfo">
<xsl:if test="generate-id() =
generate-id(key('contract', @ContractNo)[1])">
<xsl:copy>
<xsl:apply-templates select="key('contract', @ContractNo)/Details | @*" />
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="Details">
<xsl:if test="generate-id(..) =
generate-id(key('contract', ../@ContractNo)[1])">
<xsl:copy>
<xsl:apply-templates select="key('filedata', ../@ContractNo) | @*" />
</xsl:copy>
</xsl:if>
</xsl:template>
<!-- copy everything else (root node, Filedata nodes and @attributes) -->
<xsl:template match="* | @*">
<xsl:copy>
<xsl:apply-templates select="* | @*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
注意<xsl:key>结合使用generate-id()来识别匹配节点集的第一个节点,有效地将相等的节点分组在一起.
您可以<xsl:sort>在内部使用强制执行有序结果<xsl:apply-templates>.为了清楚起见,我没有包括它.
我的测试输出是:
<root>
<ContractInfo ContractNo="12345">
<Details LastName="Goodchild">
<Filedata FileName="File1"></Filedata>
<Filedata FileName="File2"></Filedata>
</Details>
</ContractInfo>
<ContractInfo ContractNo="123456">
<Details LastName="Goodchild">
<Filedata FileName="File2"></Filedata>
</Details>
</ContractInfo>
</root>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1304 次 |
| 最近记录: |