我的目标是生成一个与输入相同的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
我遇到的问题是,由替换函数产生的输出省略了除数据之外的所有内容,即使相同的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表达式的不同行为?我该如何解决这个问题?我是否需要一种完全不同的方法来实现我的目标?
答案 0 :(得分:1)
您可以使用:
<?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>