如何用XSLT修改XML文件中ComponentType标签的嵌套结构?
如何用XSLT调整XML的标签嵌套结构与属性转换?
我需要调整现有XML的标签嵌套结构:将ComponentDetails节点下的Amount、YTDAmount标签移入ComponentType标签内,并将ComponentType原文本内容转为其ID属性。
原XML内容:
<?xml version="1.0" encoding="UTF-8"?> <root> <PayrunDetails> <PayrunNumber>000777</PayrunNumber> </PayrunDetails> <PayLocation> <LocationCode>ACT</LocationCode> <LocationDescription>ACT</LocationDescription> <CompanyDetails> <CName>APPLE Limited</CName> <Payslip> <StaffNumber>12345</StaffNumber> <PayDetails> <AmountGross>9999</AmountGross> <ComponentDetails> <ComponentType>SALARY</ComponentType> <Amount>1999</Amount> <YTDAmount>10616</YTDAmount> </ComponentDetails> <ComponentDetails> <ComponentType>SALARY</ComponentType> <Amount>7305</Amount> <YTDAmount>76703</YTDAmount> </ComponentDetails> </PayDetails> </Payslip> </CompanyDetails> </PayLocation> </root>
期望输出XML:
<?xml version="1.0" encoding="UTF-8"?> <root> <PayrunDetails> <PayrunNumber>000777</PayrunNumber> </PayrunDetails> <PayLocation> <LocationCode>ACT</LocationCode> <LocationDescription>ACT</LocationDescription> <CompanyDetails> <CName>APPLE Limited</CName> <Payslip> <StaffNumber>12345</StaffNumber> <PayDetails> <AmountGross>9999</AmountGross> <ComponentDetails> <ComponentType ID="SALARY"> <Amount>1999</Amount> <YTDAmount>10616</YTDAmount> </ComponentType> </ComponentDetails> <ComponentDetails> <ComponentType ID="TAX"> <Amount>7305</Amount> <YTDAmount>76703</YTDAmount> </ComponentType> </ComponentDetails> </PayDetails> </Payslip> </CompanyDetails> </PayLocation> </root>
作为XSLT新手,我不清楚如何编写实现该需求的代码,恳请指导。
解决方案:XSLT代码实现
以下是满足你需求的XSLT样式表,我会逐部分解释它的作用:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 身份转换模板:默认复制所有节点和属性,保留不需要修改的内容 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 处理ComponentType元素:将文本内容转为ID属性,并嵌入Amount和YTDAmount --> <xsl:template match="ComponentType"> <!-- 创建带ID属性的ComponentType元素,ID值为原文本内容 --> <ComponentType ID="{.}"> <!-- 选择当前ComponentDetails下的Amount和YTDAmount,作为子节点嵌入 --> <xsl:apply-templates select="../Amount | ../YTDAmount"/> </ComponentType> </xsl:template> <!-- 隐藏原位置的Amount和YTDAmount:避免重复输出 --> <xsl:template match="ComponentDetails/Amount | ComponentDetails/YTDAmount"/> </xsl:stylesheet>
代码解释:
- 身份转换模板:这是XSLT的基础模板,它会原样复制XML中所有未被其他模板匹配的节点和属性,确保你的XML中不需要修改的部分(比如
PayrunNumber、StaffNumber等)保持不变。 - ComponentType处理模板:
- 匹配所有
ComponentType元素,创建一个新的ComponentType元素。 - 使用
{.}获取原ComponentType的文本内容(比如SALARY),将其作为ID属性的值。 - 通过
../Amount | ../YTDAmount选择当前ComponentType的父节点(ComponentDetails)下的Amount和YTDAmount元素,将它们作为子节点嵌入到新的ComponentType中。
- 匹配所有
- 隐藏原位置的Amount/YTDAmount:匹配
ComponentDetails下的这两个元素,模板内没有任何输出,这样它们就不会在原来的位置重复出现,只会出现在新的ComponentType嵌套结构里。
使用方法:
你可以将上述XSLT保存为.xsl文件,然后使用XSLT处理器(比如Saxon、Xalan)或者在线XSLT测试工具,将原XML和XSLT文件输入,即可得到期望的输出结果。
内容的提问来源于stack exchange,提问作者Stark
相关产品推荐
相关产品推荐

