我试图在进行调整时将XML文档的一部分复制到新元素中。但是,我想将源保持其原始状态,更改应仅出现在副本中。另外,必须保留文档的所有其他部分。
这里是一个示例,它试图通过将属性change =“ true”的所有元素的内容更改为大写来实现上述目的。
XML输入
<?xml version="1.0" encoding="UTF-8"?>
<root>
<original>
<element change="true">abc</element>
<element change="false">def</element>
</original>
<copy/>
<other>preserve this</other>
</root>
XSLT样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="#all" version="2.0">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/root/copy">
<copy>
<xsl:copy-of select="/root/original/*"/>
</copy>
</xsl:template>
<xsl:template match="/root/original/element[@change='true']/text()">
<xsl:value-of select="upper-case(.)"/>
</xsl:template>
</xsl:stylesheet>
当前输出
<?xml version="1.0" encoding="UTF-8"?>
<root>
<original>
<element change="true">ABC</element>
<element change="false">def</element>
</original>
<copy>
<element change="true">abc</element>
<element change="false">def</element>
</copy>
<other>preserve this</other>
</root>
但是,我当前的XSLT基本上与我想要的相反,它只将原始元素更改为大写,而将小写版本复制到“ copy”分支。
所需的输出
<?xml version="1.0" encoding="UTF-8"?>
<root>
<original>
<element change="true">abc</element>
<element change="false">def</element>
</original>
<copy>
<element change="true">ABC</element>
<element change="false">def</element>
</copy>
<other>preserve this</other>
</root>
我使用xsl:call-template进行了一些测试,但无法产生任何接近我想要的东西。
答案 0 :(得分:2)
如果您希望copy
包含更改后的输出,则应在模板中使用xsl:apply-templates
,而不是xsl:copy-of
。并且要确保original
不变,您将需要一个单独的模板来执行xsl:copy-of
。
尝试使用此XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="#all" version="2.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/root/copy">
<copy>
<xsl:apply-templates select="/root/original/*"/>
</copy>
</xsl:template>
<xsl:template match="/root/original">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="/root/original/element[@change='true']/text()">
<xsl:value-of select="upper-case(.)"/>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
Final Code
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/root/copy">
<copy>
<xsl:apply-templates select="/root/original/*"/>
</copy>
</xsl:template>
<xsl:template match="/root/original">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="/root/original/element[@change='true']/text()">
<xsl:value-of select="upper-case(.)"/>
</xsl:template>