XSLT按原样返回输入xml,除了将一个字符串替换为另一个字符串,而不管它可能出现在哪里



我的目标是生成与输入相同的XSLT输出,只是将一个字符串替换为另一个字符串,而不管它可能出现在哪里。要替换的字符串可以是数据、xml标记名、命名空间名称URI或xml文档中的任何其他字符串,我希望以任何一种方式替换它。

示例xml输入:

<?xml version="1.0" encoding="utf-8"?>
<ns:a xmlns:ns="http://www.toreplace.com" xmlns:nsB="http://www.toreplace.com/anything">
<nsB:b>
toreplace
<toreplace>
data toreplace
</toreplace>
toreplace
</nsB:b>
</ns:a>

期望输出:

<?xml version="1.0" encoding="utf-8"?>
<ns:a xmlns:ns="http://www.replaceto.com" xmlns:nsB="http://www.replaceto.com/anything">
<nsB:b>
replaceto
<replaceto>
data replaceto
</replaceto>
replaceto
</nsB:b>
</ns:a>

我迄今为止最好的尝试:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="no" indent="no"/>
<xsl:template match="*">
<xsl:copy-of select="replace(., 'toreplace', 'replaceto')"/>
</xsl:template>
</xsl:stylesheet>

这会产生输出:

<?xml version="1.0" encoding="UTF-8"?>
replaceto
data replaceto
replaceto

我面临的问题是,replace函数生成的输出省略了除数据之外的所有内容,即使在以下示例中相同的XPath表达式(点)没有省略任何内容:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="no" indent="no"/>
<xsl:template match="*">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>

生产:

<?xml version="1.0" encoding="UTF-8"?>
<ns:a xmlns:ns="http://www.toreplace.com" xmlns:nsB="http://www.toreplace.com/anything">
<nsB:b>
toreplace
<toreplace>
data toreplace
</toreplace>
toreplace
</nsB:b>
</ns:a>

是什么导致了看似相同的XPath表达式的不同行为?如何解决此问题?我需要一种完全不同的方法来实现我的目标吗?

您可以使用这个:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<!--Template to change namespace -->
<xsl:template match="*[namespace-uri()[matches(., 'toreplace')]]" priority="1">
<xsl:element name="{replace(name(), 'toreplace', 'replaceto')}" namespace="{replace(namespace-uri(), 'toreplace', 'replaceto')}">
<xsl:apply-templates select="node()|@*"></xsl:apply-templates>
</xsl:element>
</xsl:template>
<!--Identical Transform -->
<xsl:template match="node()|@*">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!--Template for Text Change -->
<xsl:template match="text()[matches(., 'toreplace')]">
<xsl:value-of select="replace(., 'toreplace', 'replaceto')"/>
</xsl:template>
<!--Template for Element name Change -->
<xsl:template match="*[matches(local-name(), 'toreplace')]">
<xsl:element name="{replace(local-name(), 'toreplace', 'replaceto')}">
<xsl:apply-templates select="node()|@*"></xsl:apply-templates>
</xsl:element> 
</xsl:template>
<!--Template for Attribute Name and Value Change -->
<xsl:template match="@*[matches(., 'toreplace') or matches(name(), 'toreplace')]">
<xsl:attribute name="{replace(local-name(), 'toreplace', 'replaceto')}">
<xsl:value-of select="replace(., 'toreplace', 'replaceto')"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>

输出

<ns:a xmlns:ns="http://www.replaceto.com">
<nsB:b xmlns:nsB="http://www.toreplace.com/anything">
replaceto
<replaceto>
data replaceto
</replaceto>
replaceto
</nsB:b>
</ns:a>

相关内容

最新更新