replacing namespace - problem with attribute's values that have namespace
i'm moving from one namespace to another in a XML and i have been facing problems with xsi:type attributes for typed elements. I have been using next template that easily moves element that have one namespace to other one.
<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>
but i'm not able to update attribute values that belongs to a given name space as xsi:type attribute.
<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/&g开发者_如何转开发t;
</soap:Envelope>
In above example, i can't change "nsold:atype" to one like "ns3New:atype" that uses the new name spaces. Is there any way to do adjust this kind of values?
Your problem here is that nsold:aType
is the textual value of the attribute; It doesn't have a namespace, it's just text. You need a template that modifies the content of the attribute. You might need to adapt it to your needs, but this should demonstrate how to do this:
<xsl:template match="@*[starts-with(.,'nsold:')]">
<xsl:attribute name="{name()}">
<xsl:value-of select="concat('ns3New:',substring-after(.,'nsold:'))" />
</xsl:attribute>
</xsl:template>
This simply substitutes the content of any attribute with text beginning in 'nsold:' with 'ns3New:etc.' instead.
The "correct" way to do this is probably with a schema-aware transformation, which recognizes the xsi:type as being of type attribute(*, xs:QName). You can then do an identity transformation supplemented with
<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>
where f:new-prefix() is a function that maps the namespace URI of the QName to the prefix to be used in the new document.
However, if xsi:type is your only namespace-sensitive content, then you could just handle it as a special case.
精彩评论