我有以下XML:
<records>
<record>
<id>111</id>
<amount>123.45</amount>
<taxCode>A</taxCode>
</record>
</records>
我需要复制上面的所有节点,但也要创建一些具有特定值的节点的额外副本,比如说,taxCode。 我将如何实现以下目标:
<records>
<record>
<id>111</id>
<amount>123.45</amount>
<taxCode>A</taxCode>
</record>
<!-- copy of the node above with amount and taxCode changed -->
<record>
<id>111</id>
<amount>-123.45</amount>
<taxCode>B</taxCode>
</record>
</records>
我尝试使用以下简单的XSL,但只复制一次:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"
encoding="UTF-8"
omit-xml-declaration="no"
indent="yes" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="records/taxCode[text() = 'A']" >
<xsl:copy select="node()" />
</xsl:template>
</xsl:stylesheet>
对此有任何帮助表示赞赏。
答案 0 :(得分:1)
怎么样:
<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="records">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select="record[taxCode='A']" mode="B"/>
</xsl:copy>
</xsl:template>
<xsl:template match="record" mode="B">
<xsl:copy>
<xsl:copy-of select="id"/>
<amount>
<xsl:value-of select="-amount"/>
</amount>
<taxCode>B</taxCode>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
或者,如果您愿意:
<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="record[taxCode='A']" >
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
<xsl:copy>
<xsl:copy-of select="id"/>
<amount>
<xsl:value-of select="-amount"/>
</amount>
<taxCode>B</taxCode>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
这是一个通用转换,它允许动态指定新旧税码之间的映射:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes"/>
<my:Mapping>
<code old="A">B</code>
<code old="M">P</code>
</my:Mapping>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*" mode="new">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="new"/>
</xsl:copy>
</xsl:template>
<xsl:template match="record[taxCode = document('')/*/my:Mapping/*/@old]">
<xsl:call-template name="identity"/>
<xsl:apply-templates select="." mode="new"/>
</xsl:template>
<xsl:template mode="new"
match="record[taxCode = document('')/*/my:Mapping/*/@old]/amount/text()" >
<xsl:value-of select="-1*."/>
</xsl:template>
<xsl:template mode="new"
match="record[taxCode = document('')/*/my:Mapping/*/@old]/taxCode/text()" >
<xsl:value-of select="document('')/*/my:Mapping/*[@old = current()]"/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下XML文档:
<records>
<record>
<id>111</id>
<amount>123.45</amount>
<taxCode>A</taxCode>
</record>
<record>
<id>111</id>
<amount>123.45</amount>
<taxCode>C</taxCode>
</record>
<record>
<id>111</id>
<amount>123.45</amount>
<taxCode>M</taxCode>
</record>
</records>
产生了想要的正确结果:
<records>
<record>
<id>111</id>
<amount>123.45</amount>
<taxCode>A</taxCode>
</record><record>
<id>111</id>
<amount>-123.45</amount>
<taxCode>B</taxCode>
</record>
<record>
<id>111</id>
<amount>123.45</amount>
<taxCode>C</taxCode>
</record>
<record>
<id>111</id>
<amount>123.45</amount>
<taxCode>M</taxCode>
</record><record>
<id>111</id>
<amount>-123.45</amount>
<taxCode>P</taxCode>
</record>
</records>
请注意:
my:Mapping
树通常位于自己独立的XML文档(文件)中,当映射发生更改时,不必更改转换。