Subject: RE: RE: unwanted and non prefix namespaces in output
From: "Michael Kay" <mhk@xxxxxxxxx>
Date: Sun, 1 Aug 2004 13:00:40 +0100
|
> Michael,
>
> Thanks, that did fix the problem. Out of curiosity (strictly academic
> as my stylesheet does what I need it to), is there a more elegant
> solution to the problem? Or is the stylesheet I wrote along
> the correct
> lines?
>
One could make minor tweaks but nothing radical. When using the identity
template I don't normally apply templates to attributes unless there are
changes to be made, I normally copy them using <xsl:copy-of select="@*"/>.
And where the body of a template rule consists entirely of an xsl:choose, I
would normally split it into multiple template rules, moving the "test"
condition to be part of the match pattern. (You can't do this in 1.0 if it
references a variable, but yours doesn't).
Michael Kay
>
> -----Original Message-----
> From: Michael Kay [mailto:mhk@xxxxxxxxx]
> Sent: Saturday, July 31, 2004 5:20 AM
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: RE: RE: unwanted and non prefix namespaces in output
>
> I don't know what XSLT processor you're using, but the output
> I'm seeing
> from Saxon (which I believe is correct) starts:
>
> <sequence xmlns:ads="http://schemas.microsoft.com/ads/2003/sequence"
> version="1" description="foo" command="bar">
>
> <sequence version="1" description="Image" command="WIN2000">
>
> <task xmlns="http://schemas.microsoft.com/ads/2003/sequence">
>
> The first <sequence> element is generated from a literal
> result element
> in your stylesheet. It is in no namespace because the
> stylesheet doesn't
> put it in a namespace. It copies the declaration of xmlns:ads from the
> stylesheet because that's what literal result elements do.
>
> The second <sequence> element is the same, but it doesn't redeclare
> xmlns:ads because that would be redundant.
>
> The <task> element is generated by copying from the source
> document. The
> element is in the ads/2003 namespace because it stays in the same
> namespace when you copy it. The original <task> element has
> an in-scope
> namespace with prefix "" and uri "http://....ads/2003/...", so the
> copied element has one too.
>
> I think, if I understand your problem description, that you probably
> want to write <xsl:copy> where you currently write
> <sequence>. That way
> you will get the namespaces that are in scope for the source element,
> not those that are in scope in the stylesheet.
>
> You made a lot of headway in four hours...
>
> Michael Kay
>
> > -----Original Message-----
> > From: Joel Friedman [mailto:jfriedman@xxxxxxxxxxxx]
> > Sent: 31 July 2004 07:09
> > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > Subject: RE: unwanted and non prefix namespaces in output
> >
> > I am very new to xslt (approx 4 hours) but I have managed to
> > (mostly) do
> > the simple task I am trying to perform.
> >
> > I am attempting to take an xml file in this format (greatly
> shortened
> > for simplicity):
> >
> > <?xml version="1.0" encoding="utf-16"?> <sequence version="1"
> > description="foo" command="bar"
> > xmlns="http://schemas.microsoft.com/ads/2003/sequence">
> >
> > <sequence version="1" description="Image" command="WIN2000"
> > xmlns="http://schemas.microsoft.com/ads/2003/sequence">
> > <task>
> > <command>foo</command>
> > <parameters>
> > <parameter>bar</parameter>
> > </parameters>
> > </task>
> > <task>
> > ...
> > </task
> > </sequence>
> >
> > <sequence version="1" description="Patch" command="WIN2000"
> > xmlns="http://schemas.microsoft.com/ads/2003/sequence">
> > <task>
> > <command>foo</command>
> > <parameters>
> > <parameter>bar</parameter>
> > </parameters>
> > </task>
> > <task>
> > ...
> > </task
> > </sequence>
> >
> > <sequence version="1" description="Patch" command="WIN2K3"
> > xmlns="http://schemas.microsoft.com/ads/2003/sequence">
> > <task>
> > <command>foo</command>
> > <parameters>
> > <parameter>bar</parameter>
> > </parameters>
> > </task>
> > <task>
> > ...
> > </task
> > </sequence>
> >
> > <sequence version="1" description="foo" command="bar"
> > xmlns="http://schemas.microsoft.com/ads/2003/sequence">
> > ...
> > </sequence>
> >
> > ...
> >
> > </sequence>
> >
> >
> > And apply this XSL:
> >
> > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> >
> > xmlns:ads="http://schemas.microsoft.com/ads/2003/sequence"
> > version="1.0">
> >
> > <xsl:output method="xml" indent="yes"/>
> > <xsl:variable name="osName"
> > select="ads:sequence/ads:sequence/@command"/>
> >
> > <xsl:template match="/">
> > <xsl:apply-templates select="ads:sequence"/>
> > </xsl:template>
> >
> > <xsl:template match="ads:sequence">
> > <xsl:choose>
> > <xsl:when test="(@description='Patch')">
> > <xsl:if test="@command=$osName">
> > <sequence>
> > <xsl:apply-templates select="@*|node()"/>
> > </sequence>
> > </xsl:if>
> > </xsl:when>
> > <xsl:otherwise>
> > <sequence>
> > <xsl:apply-templates select="@*|node()"/>
> > </sequence>
> > </xsl:otherwise>
> > </xsl:choose>
> > </xsl:template>
> >
> > <xsl:template match="@*|node()">
> > <xsl:copy>
> > <xsl:apply-templates select="@*|node()"/>
> > </xsl:copy>
> > </xsl:template>
> >
> > </xsl:stylesheet>
> >
> >
> > Basically I'm trying to fetch the OS Name from the command
> attribute
> > of the second sequence (fixed location) Then the if OS matches the
> > command attribute for the sequence with a description of
> 'Patch', copy
>
> > it over.
> > Also copy over everything else that isn't a Patch sequence. So
> > basically my output should be identical to my input minus the Patch
> > sequence where the OS does not match. My problem enlies that every
> > 'task ' element has the namespace added to it but the
> sequence element
>
> > does not.
> >
> > ..sample output:
> >
> > <?xml version="1.0" encoding="UTF-16"?> <sequence version="1"
> > description="foo" command="bar">
> >
> > <sequence version="1" description="Image" command="WIN2000">
> > <task xmlns="http://schemas.microsoft.com/ads/2003/sequence">
> > <command>foo</command>
> > <parameters>
> > <parameter>bar</parameter>
> > </parameters>
> > </task>
> >
> >
> > The exclude-result-prefixes="ads" squashed my namespace on the root
> > sequence element (which I don't want). I need the
> namespace to only
> > be defined on all sequence blocks. Just like the input. The logic
> > part of not copying over the block I do not need does work. It's
> > probably not the best way, but it is functional. Forgive
> me if I did
> > not use the correct XSL grammar while trying to explain my problem.
> >
> > Anybody have an idea of a direction I should look in for a solution?
> >
> > Thanks in advance,
> >
> > --Joel
> >
> > ________________________________
> >
> > From: Joel Friedman
> > Sent: Saturday, July 31, 2004 2:07 AM
> > To: 'xsl-list@xxxxxxxxxxxxxxxxxxxxxx'
> > Subject: unwanted and non prefix namespaces in output
> >
> >
> > I am very new to xslt (approx 4 hours) but I have managed to
> > (mostly) do
> > the simple task I am trying to perform.
> >
> > I am attempting to take an xml file in this format (greatly
> shortened
> > for simplicity):
> >
> > <?xml version="1.0" encoding="utf-16"?> <sequence version="1"
> > description="foo" command="bar"
> > xmlns="http://schemas.microsoft.com/ads/2003/sequence">
> >
> > <sequence version="1" description="Image" command="WIN2000"
> > xmlns="http://schemas.microsoft.com/ads/2003/sequence">
> > <task>
> > <command>foo</command>
> > <parameters>
> > <parameter>bar</parameter>
> > </parameters>
> > </task>
> > <task>
> > ...
> > </task
> > </sequence>
> >
> > <sequence version="1" description="Patch" command="WIN2000"
> > xmlns="http://schemas.microsoft.com/ads/2003/sequence">
> > <task>
> > <command>foo</command>
> > <parameters>
> > <parameter>bar</parameter>
> > </parameters>
> > </task>
> > <task>
> > ...
> > </task
> > </sequence>
> >
> > <sequence version="1" description="Patch" command="WIN2K3"
> > xmlns="http://schemas.microsoft.com/ads/2003/sequence">
> > <task>
> > <command>foo</command>
> > <parameters>
> > <parameter>bar</parameter>
> > </parameters>
> > </task>
> > <task>
> > ...
> > </task
> > </sequence>
> >
> > <sequence version="1" description="foo" command="bar"
> > xmlns="http://schemas.microsoft.com/ads/2003/sequence">
> > ...
> > </sequence>
> >
> > ...
> >
> > </sequence>
> >
> >
> > And apply this XSL:
> >
> > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> >
> > xmlns:ads="http://schemas.microsoft.com/ads/2003/sequence"
> > version="1.0">
> >
> > <xsl:output method="xml" indent="yes"/>
> > <xsl:variable name="osName"
> > select="ads:sequence/ads:sequence/@command"/>
> >
> > <xsl:template match="/">
> > <xsl:apply-templates select="ads:sequence"/>
> > </xsl:template>
> >
> > <xsl:template match="ads:sequence">
> > <xsl:choose>
> > <xsl:when test="(@description='Patch')">
> > <xsl:if test="@command=$osName">
> > <sequence>
> > <xsl:apply-templates select="@*|node()"/>
> > </sequence>
> > </xsl:if>
> > </xsl:when>
> > <xsl:otherwise>
> > <sequence>
> > <xsl:apply-templates select="@*|node()"/>
> > </sequence>
> > </xsl:otherwise>
> > </xsl:choose>
> > </xsl:template>
> >
> > <xsl:template match="@*|node()">
> > <xsl:copy>
> > <xsl:apply-templates select="@*|node()"/>
> > </xsl:copy>
> > </xsl:template>
> >
> > </xsl:stylesheet>
> >
> >
> > Basically I'm trying to fetch the OS Name from the command
> attribute
> > of the second sequence (fixed location) Then the if OS matches the
> > command attribute for the sequence with a description of
> 'Patch', copy
>
> > it over.
> > Also copy over everything else that isn't a Patch sequence. So
> > basically my output should be identical to my input minus the Patch
> > sequence where the OS does not match. My problem enlies that every
> > 'task ' element has the namespace added to it but the
> sequence element
>
> > does not.
> >
> > ..sample output:
> >
> > <?xml version="1.0" encoding="UTF-16"?> <sequence version="1"
> > description="foo" command="bar">
> >
> > <sequence version="1" description="Image" command="WIN2000">
> > <task xmlns="http://schemas.microsoft.com/ads/2003/sequence">
> > <command>foo</command>
> > <parameters>
> > <parameter>bar</parameter>
> > </parameters>
> > </task>
> >
> >
> > The exclude-result-prefixes="ads" squashed my namespace on the root
> > sequence element (which I don't want). I need the
> namespace to only
> > be defined on all sequence blocks. Just like the input. The logic
> > part of not copying over the block I do not need does work. It's
> > probably not the best way, but it is functional. Forgive
> me if I did
> > not use the correct XSL grammar while trying to explain my problem.
> >
> > Anybody have an idea of a direction I should look in for a solution?
> >
> > Thanks in advance,
> >
> > --Joel
|