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

Subject: RE: [xsl] Modifying namespace definitions in xs:schema elements
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Sun, 11 Oct 2009 11:26:54 +0100
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.

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.

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