xsl-list
[Top] [All Lists]

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

2009-10-11 08:12:06
On Sun, Oct 11, 2009 at 12:26 PM, Michael Kay <mike(_at_)saxonica(_dot_)com> 
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(_dot_)laun(_at_)gmail(_dot_)com]
Sent: 11 October 2009 10:00
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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(_at_)cranesoftwrights(_dot_)com> 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(_at_)CraneSoftwrights(_dot_)com
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--