我有这个xml:
<pos:getPositionRouter xmlns:pos="positionNS">
<positionID>
<code>1</code>
</positionID>
<parameter>?</parameter>
</pos:getPositionRouter>
我想使用xslt将元素pos:getPositionRouter
重命名为x:getPosition
:
<x:getPosition xmlns:x="newPositionNS">
<positionID>
<code>1</code>
</positionID>
<parameter>?</parameter>
</x:getPosition>
这是我提出的sylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:param name="old_namespace" />
<xsl:param name="old_element_localname" />
<xsl:param name="new_namespace" />
<xsl:param name="new_element_localname" />
<xsl:template match="@*|node()">
<xsl:choose>
<xsl:when test="(local-name() = $old_element_localname) and (namespace-uri() = $old_namespace)">
<xsl:element name="{$new_element_localname}" namespace="{$new_namespace}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:when>
<!-- copy the rest as is -->
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
我被迫使用xalan作为xslt处理器,输出不幸的是:
<getPosition xmlns="newPositionNS">
<positionID xmlns:pos="positionNS">
<code>1</code>
</positionID>
<parameter xmlns:pos="positionNS">?</parameter>
</getPosition>
getPosition
元素的默认命名空间成为新的命名空间,但子元素应保持不带命名空间(xmlns=""
)。
有人能理解为什么吗?
谢谢!
答案 0 :(得分:1)
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="old_namespace" select="'positionNS'"/>
<xsl:param name="old_element_localname" select="'getPositionRouter'"/>
<xsl:param name="new_namespace_prefix" select="'x'"/>
<xsl:param name="new_namespace" select="'newPositionNS'"/>
<xsl:param name="new_element_localname" select="'getPosition'" />
<xsl:template match="*">
<xsl:choose>
<xsl:when test="local-name()=$old_element_localname and
namespace-uri()=$old_namespace">
<xsl:element
name="{substring(concat($new_namespace_prefix,':'),
1 div boolean($new_namespace_prefix))}{
$new_element_localname}"
namespace="{$new_namespace}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
输出:
<x:getPosition xmlns:x="newPositionNS">
<positionID>
<code>1</code>
</positionID>
<parameter>?</parameter>
</x:getPosition>
注意:如果您需要特定的前缀,则应将其添加到QName。如果要删除范围内的命名空间,则不应在XSLT 1.0中使用xsl:copy
答案 1 :(得分:0)
<强>予。不使用参数进行转换非常简短:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:pos="positionNS" xmlns:x="newPositionNS" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="pos:getPositionRouter">
<xsl:element name="x:getPosition">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:copy-of select="namespace::*[not(name()='pos')]"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<pos:getPositionRouter xmlns:pos="positionNS">
<positionID>
<code>1</code>
</positionID>
<parameter>?</parameter>
</pos:getPositionRouter>
产生了想要的正确结果:
<x:getPosition xmlns:x="newPositionNS">
<positionID>
<code>1</code>1
</positionID>
<code>1</code>1
<parameter>?</parameter>?
</x:getPosition>
II。 参数化转换稍微复杂一点:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pOldNamespace" select="'positionNS'"/>
<xsl:param name="pOldElementLocalname" select="'getPositionRouter'"/>
<xsl:param name="pNewNamespace" select="'newPositionNS'"/>
<xsl:param name="pNewElementLocalname" select="'getPosition'"/>
<xsl:param name="pNewElementPrefix" select="'x'"/>
<xsl:template match="*">
<xsl:variable name="vReplacing" select=
"local-name()=$pOldElementLocalname
and
namespace-uri()=$pOldNamespace"/>
<xsl:variable name="vName">
<xsl:choose>
<xsl:when test="$vReplacing">
<xsl:value-of select="concat($pNewElementPrefix, ':', local-name())"/>
</xsl:when>
<xsl:otherwise><xsl:value-of select="name()"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="vNamespace">
<xsl:choose>
<xsl:when test="$vReplacing">
<xsl:value-of select="$pNewNamespace"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="namespace-uri()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$vName}" namespace="{$vNamespace}">
<xsl:copy-of select="namespace::*[not(.=$pOldNamespace)]"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>