我在XML中从一个名称空间移动到另一个名称空间,并且我遇到了类型化元素的xsi:type属性问题。 我一直在使用下一个模板,可以轻松地将具有一个名称空间的元素移动到另一个
<xsl:template match="ent:*" >
<xsl:element name="ent:{local-name()}"
namespace="http://ns3">
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
但我无法将属于给定名称空间的属性值更新为xsi:type属性。
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ser:getAsByIdResponse xmlns:ser="http://osde.com.ar/services">
<return xmlns:xsi=".." xmlns:ns3New="http://ns3" xmlns:ns1New="http://ns2" xsi:type="nsold:aType"/>
</ser:getAsByIdResponse>
</soap:Body/>
</soap:Envelope>
在上面的示例中,我无法将“nsold:atype”更改为使用新名称空间的“ns3New:atype”。 有没有办法调整这种价值观?
答案 0 :(得分:1)
这里的问题是nsold:aType
是属性的文本值;它没有命名空间,只是文本。您需要一个修改属性内容的模板。您可能需要根据自己的需要进行调整,但这应该说明如何执行此操作:
<xsl:template match="@*[starts-with(.,'nsold:')]">
<xsl:attribute name="{name()}">
<xsl:value-of select="concat('ns3New:',substring-after(.,'nsold:'))" />
</xsl:attribute>
</xsl:template>
这只是用'nsold:'开头的文本替换任何属性的内容,用'ns3New:etc。'代替。
答案 1 :(得分:1)
执行此操作的“正确”方法可能是使用模式感知转换,它将xsi:type识别为type属性(*,xs:QName)。然后,您可以进行身份转换,并辅以
<xsl:template match="attribute(*, xs:QName)">
<xsl:attribute name="{local-name()}" namespace="{namespace-uri()}"
select="concat(f:new-prefix(namespace-uri-from-QName(.)),
':', local-name-from-QName(.))"/>
</xsl:template>
其中f:new-prefix()是一个函数,它将QName的名称空间URI映射到要在新文档中使用的前缀。
但是,如果xsi:type是您唯一的名称空间敏感内容,那么您可以将其作为特殊情况处理。