2011-07-04 150 views
1

我正在从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

那么,什么是源XML文档,以及需要转换为什么是需要的XML文档?为什么一个愿意回答的人必须猜测这些?请编辑您的问题并提供缺失的数据。 –

回答

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:等”代替。

+0

使用XPath 1.0时,属性的值类型的正确名称是“字符串值” - 不是“文本值”。根据规范:http://www.w3.org/TR/xpath/#dt-string-value –

+0

那么,如果你要分割头发,正确的名字是'string-value'(注意连字符),但是我描述了属性的内容,没有命名它的类型,所以它并不真正相关。谢谢你指出,虽然。 – Flynn1179

1

执行此操作的“正确”方法可能是使用模式感知转换,它将xsi: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标识转换,新的前缀()是一个新的文件中使用的QName的前缀的命名空间URI映射功能。

但是,如果xsi:type是您唯一的名称空间敏感内容,那么您可以将其作为特殊情况处理。

+0

这可能是值得一提的,这意味着使用XSLT2处理器。 – Flynn1179