1

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/>

   </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?

user828814
  • 11
  • 2
  • So, what is the source XML document and what is the wanted XML document that it must be transformed to? Why should a person who is willing to answer have to guess these? Please, edit your question and provide the missing data. – Dimitre Novatchev Jul 05 '11 at 02:37

2 Answers2

1

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.

Flynn1179
  • 11,925
  • 6
  • 38
  • 74
  • The proper name of the value type of an attribute when using XPath 1.0 is "string value" -- not "textual value". As per spec: http://www.w3.org/TR/xpath/#dt-string-value – Dimitre Novatchev Jul 05 '11 at 12:57
  • Well, if you're going to split hairs about it, the proper name is `string-value` (note the hyphen), however I was describing the content of the attribute, not naming it's type, so it's not really relevant. Thanks for pointing that out though. – Flynn1179 Jul 05 '11 at 13:09
1

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.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164