Re: [xsl] Modifying namespace definitions in xs:schema elements

Subject: Re: [xsl] Modifying namespace definitions in xs:schema elements
From: Wolfgang Laun <wolfgang.laun@xxxxxxxxx>
Date: Sun, 11 Oct 2009 14:11:32 +0200
On Sun, Oct 11, 2009 at 12:26 PM, Michael Kay <mike@xxxxxxxxxxxx> wrote:
>
> The processors you have mentioned are all XSLT 1.0 processors, so they
> should give you an error when you attempt to execute an xsl:namespace
> instruction (which is new in XSLT 2.0). However, it's known that the
> behaviour of XSLT 1.0 processors when the stylesheet says version="2.0"
> doesn't always follow the 1.0 (or 2.0) spec.

Confusing.

>
> With an XSLT 2.0 processor, you don't need to create the dummy attribute
> com:blech and you don't need to declare the com namespace.
>

Saxon-HE 9.2.0.2J does it. (Any other OS options?)

Thanks.
-W

> Regards,
>
> Michael Kay
> http://www.saxonica.com/
> http://twitter.com/michaelhkay
>
>> -----Original Message-----
>> From: Wolfgang Laun [mailto:wolfgang.laun@xxxxxxxxx]
>> Sent: 11 October 2009 10:00
>> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
>> Subject: Re: [xsl] Modifying namespace definitions in
>> xs:schema elements
>>
>> Ken,
>>
>> first, thank you for the quick reply. It wasn't smooth
>> sailing, but I think I've reached home port. Below is the
>> complete stylesheet, with comments to tell y'all the tacks
>> and turns I made. (This is only my third day of XSLT
>> programming, so I'll admit that I was using the W3C document
>> for version 1.0 as a reference :-\ )
>>
>> Best,
>> Wolfgang
>>
>> The XSLT processors I'm using (on Linux/Ubuntu)
>>
>> $ xsltproc --version
>> Using libxml 20632, libxslt 10124 and libexslt 813 xsltproc
>> was compiled against libxml 20632, libxslt 10124 and libexslt
>> 813 libxslt 10124 was compiled against libxml 20632 libexslt
>> 813 was compiled against libxml 20632
>>
>> xalan-j_2_7_1
>>
>> The XSLT:
>> <?xml version="1.0"?>
>> <xsl:stylesheet version="2.0"
>>     xmlns:xs="http://www.w3.org/2001/XMLSchema";
>>     xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>>     xmlns:com="a.b.com">
>> <!--XXX Up here I had to add the namespace prefix definition
>> for the one to be added to xs:schema,  otherwise the XSLT
>> processors would refuse the use of 'com', below. -->
>>
>> <xsl:template match="xs:schema">
>>  <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
>>
>> <!--XXX Without the com prefix, <xsl:namespace> has no effect
>> on <xs:schema>. But the introduced namespace is propagated to
>> child nodes, as can be seen when not not using a prefix and
>> not reconstructing descendants. -->
>>    <xsl:namespace name="com">a.b.com</xsl:namespace>
>>    <xsl:attribute name="targetNamespace">a.b.com</xsl:attribute>
>>
>>  <!--XXX This, too, appears to be required to make xmlns:com="..."
>> appear in <xs:schema>. -->
>>    <xsl:attribute name="com:blech">42</xsl:attribute>
>>    <xsl:copy-of select="@*"/>
>>    <xsl:apply-templates/>
>>  </xsl:element>
>> </xsl:template>
>>
>> <!--XXX Reconstructing elements below <xs:schema> to avoid
>> the introduction of xmlns:com="..." all over the place
>> doesn't appear to be necessary now. --> <xsl:template match="*" >
>>   <xsl:copy>
>>     <xsl:apply-templates select="* | @* | text()"/>
>>   </xsl:copy>
>> </xsl:template>
>>
>> <xsl:template match="@* | comment() |
>> processing-instruction() | text()">
>>  <xsl:copy/>
>> </xsl:template>
>>
>> <xsl:template match="xs:element">
>>   <xsl:copy>
>>     <xsl:for-each select="node() | @*">
>>       <xsl:choose>
>>         <xsl:when test="node()">
>>           <xsl:copy-of select="."/>
>>         </xsl:when>
>>
>> <!--XXX The whole point of the exercise: targetNamespace is
>> used in attribute values only.
>> There is a note in
>> http://www.w3.org/TR/xslt20/#creating-namespace-nodes which
>> addresses exactly this issue: "It is rarely necessary...
>> needed is a situation where the required namespace is used
>> only within attribute values in the result document..." Is it
>> possible that implementations overlook this rare occasion? -->
>>         <xsl:when test="name(.)='type' and not(contains(.,':')) ">
>>           <xsl:attribute name="type">
>>             <xsl:value-of select="concat('com:',.)"/>
>>           </xsl:attribute>
>>         </xsl:when>
>>         <xsl:otherwise>
>>           <xsl:copy/>
>>         </xsl:otherwise>
>>       </xsl:choose>
>>     </xsl:for-each>
>>   </xsl:copy>
>> </xsl:template>
>> </xsl:stylesheet>
>>
>> Input:
>> <?xml version="1.0" encoding="utf-8"?>
>> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
>>            version="0.107">
>>
>>   <xs:complexType name="FooType">
>>     <xs:sequence>
>>       <xs:element name="el1" type="xs:string"/>
>>     </xs:sequence>
>>   </xs:complexType>
>>
>>   <xs:complexType name="BarType">
>>     <xs:sequence>
>>       <xs:element name="el2" type="FooType"/>
>>     </xs:sequence>
>>   </xs:complexType>
>>
>> </xs:schema>
>>
>> Result of XSLT:
>> <?xml version="1.0" encoding="UTF-8"?><xs:schema
>> xmlns:xs="http://www.w3.org/2001/XMLSchema"; targetNamespace="a.b.com"
>> xmlns:com="a.b.com" com:blech="42" version="0.107">
>>
>>   <xs:complexType name="FooType">
>>     <xs:sequence>
>>       <xs:element name="el1" type="xs:string"/>
>>     </xs:sequence>
>>   </xs:complexType>
>>
>>   <xs:complexType name="BarType">
>>     <xs:sequence>
>>       <xs:element name="el2" type="com:FooType"/>
>>     </xs:sequence>
>>   </xs:complexType>
>>
>> </xs:schema>
>>
>>
>> On Sat, Oct 10, 2009 at 9:22 PM, G. Ken Holman
>> <gkholman@xxxxxxxxxxxxxxxxxxxx> wrote:
>> >
>> > At 2009-10-10 21:09 +0200, Wolfgang Laun wrote:
>> >>
>> >> given an XML Schema, I should split this schema into two parts,
>> >> according to properties of elements and complex/simpleTypes.
>> >> Basically, I've succeeded to do this, using a couple of XSLT
>> >> transformations. But...
>> >>
>> >> The original schema contains <xs:schema ... xmlns="a.b"
>> >> targetNamespace="a.b" ...>. I would like to modify this for one of
>> >> the results of the filtering, to become, e.g., xmlns="a.b.c"
>> >> targetNamespace="a.b.c". (The ultimate goal is to separate the
>> >> definitions made by the splt schemas into two different
>> namespaces.)
>> >
>> > Fine.
>> >
>> >> Exploring the set of attributes in xs:schema (by <xsl:choose>
>> >> <xsl:when test="true()"> <xsl:value-of
>> >> select="concat(namespace-uri(),local-name())"/>...) has
>> shown me that
>> >> the namespace definitions (xmlns="...") are not passed to template
>> >> processing.
>> >
>> > False.
>> >
>> > Namespace definitions are not passed to template processing
>> as attribute nodes, but they are passed to template
>> processing as namespace nodes.
>> >
>> >> Does this mean that what I want to be done cannot be
>> achieved at all,
>> >> using XSLT techniques?
>> >
>> > No, what you want can be done.  I hope the example below helps.
>> >
>> > . . . . . . Ken
>> >
>> > T:\ftemp>type wolfgang.xml
>> > <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
>> >           xmlns="a.b"
>> >           targetNamespace="a.b">
>> >
>> > <xs:element name="doc">
>> >  <xs:complexType>
>> >    ...
>> >  </xs:complexType>
>> > </xs:element>
>> >
>> > </xs:schema>
>> >
>> > T:\ftemp>xslt2 wolfgang.xml wolfgang.xsl <?xml version="1.0"
>> > encoding="UTF-8"?><xs:schema xmlns="a.b.c"
>> > xmlns:xs="http://www.w3.org/2001/XMLSchema"; targetNamespace="a.b.c">
>> >
>> > <xs:element name="doc">
>> >  <xs:complexType>
>> >    ...
>> >  </xs:complexType>
>> > </xs:element>
>> >
>> > </xs:schema>
>> > T:\ftemp>type wolfgang.xsl
>> > <?xml version="1.0" encoding="US-ASCII"?> <xsl:stylesheet
>> > xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>> >                xmlns:xsd="http://www.w3.org/2001/XMLSchema";
>> >                version="2.0">
>> >
>> > <!--recreate the document element when encountered--> <xsl:template
>> > match="xsd:schema">
>> >  <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
>> >    <xsl:copy-of select="@*"/>
>> >    <!--replacing the target namespace information-->
>> >    <xsl:namespace name="">a.b.c</xsl:namespace>
>> >    <xsl:attribute name="targetNamespace">a.b.c</xsl:attribute>
>> >    <!--rest of the document-->
>> >    <xsl:apply-templates/>
>> >  </xsl:element>
>> > </xsl:template>
>> >
>> > <!--recostitute all other elements to avoid copying namespaces-->
>> > <xsl:template match="*">
>> >  <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
>> >    <xsl:apply-templates select="@*,node()"/>
>> >  </xsl:element>
>> > </xsl:template>
>> >
>> > <xsl:template match="@* | comment() | processing-instruction">
>> >  <xsl:copy/>
>> > </xsl:template>
>> >
>> > </xsl:stylesheet>
>> >
>> > T:\ftemp>
>> >
>> > --
>> > Upcoming: hands-on code list, UBL, XSLT, XQuery and XSL-FO
>> classes in
>> > Copenhagen Denmark and Washington DC USA, October/November 2009
>> > Interested in other classes?  http://www.CraneSoftwrights.com/s/i/
>> > Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
>> > Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
>> > Video lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
>> > Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
>> > G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
>> > Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
>> > Legal business disclaimers:  http://www.CraneSoftwrights.com/legal

Current Thread