Home. 
.

transparent

transparent

transparent

Altova Mailing List Archives


Re: Merge two XML docments with XSLT

From: "Daniel" <softwareengineer98037@-----.--->
To: NULL
Date: 9/13/2004 11:36:00 AM
That was very helpful. Thank you.



"Marrow" <m--a-r-r-o-w@m-a-r-r-o-w--s-o-f-t.com> wrote in message
news:OmsLMx%23lEHA.3824@T......
> Hi Daniel,
>
> > This probably a dumb question but is
> >
> > <xsl:apply-templates select="@* | node()"/>
> >
> > The same as
> >
> > <xsl:apply-templates select="node()"/>
> >
> > Since node() gets all child nodes of any type?
> >
>
> No, not a dumb question - the terminology can get a little misleading.
When
> you are taking about an XML DOM then 'node' means every component part of
> the document (much in the common sense of the word 'node').  But when you
> are talking about XPath then there are 3 different axis - the node axis,
the
> attribute axis and the namespace axis.  The node test node() only tests
for
> items on the node axis - which are:- elements, text nodes, comments,
> processing instructions and that special one we call the document root
node
> (not to be confused with the document root element).
>
> So, in short, no those two expressions are not the same...
>
>  <xsl:apply-templates select="@* | node()"/>
> selects all nodes on the node axis (elements, text nodes, comments, pi's
and
> doc root node) unioned with everything on the attribute axis.
>
> whereas...
>  <xsl:apply-templates select="node()"/>
> only selects nodes on the node axis but no attributes.
>
>
> [from your other posting]...
>
> > What does this code segment do?
> >
> > <xsl:template match="@* | text() | comment() |
> > processing-instruction()"><!--  -->
> >   <xsl:copy/><!-- Creates a copy of the current node (without child
nodes
> > and attributes) -->
> > </xsl:template>
> > </xsl:stylesheet>
> >
> > It has no mode so im not sure how it is called by the other templates.
If
> it
> > applies for all attributes, text, cmments and processing-instructions in
> the
> > souce document then what keeps it from over writing the work of the
other
> > templates?
>
> It copies everything that was caught by that template - specifically, it
> copies all attributes, text nodes, comments and processing instructions
that
> were caught by this template.  Matched templates are not 'called' as
such -
> they are matched against node-sets that are pushed out by an
> <xsl:apply-templates> (or <xsl:apply-imports>).  You can imagine the
> <xsl:apply-templates> as something like throwing everything it selects up
in
> the air - and the right templates will know which of those to catch.
>
> > what keeps it from over writing the work of the other templates?
>
> Because templates are matched based primarily on a 'best match' priority
> (there are other considerations too - but that will get far too
complicated
> here).  So a template that more specifically matches something will
override
> a template that has a more 'generic' match.
> As a simple example, if you did...
>   <xsl:apply-templates select="foo"/>
> and had two templates...
>   <xsl:template match="*">
>     ...
>   </xsl:template>
>   <xsl:template match="foo">
>     ...
>   </xsl:template>
> then it would be the second of those templates that would be applied -
> because it has a more specific match.
>
>
> > Is there anything else that needs to be done besides changing the maps
> > variable?
> >     Would like to ensure that
> >         - <top> is the root node of the resulting document
> >         - <mapswithdata> wrapper is not in resulting document
> >         - <maps> mapping data does not appear in the resulting document
> >         - The root node of the resulting document remains <top>
>
> OK, 3 of those are more or less the same thing - ensuring that <top> is
the
> document root element of the output.  The other is ensuring that
> <mapswithdata> (and its children) does not appear in the output.
> You are dealing with a push processing stylesheet (push just means we are
> pushing nodes out for processing using <xsl:apply-templates> - as opposed
to
> pulling nodes using <xsl:for-each>).  The stylesheet is we already have is
> also based loosely on an idenity transform (an identity transform is one
> that, for the most part, copies the input document as is but with some
> exception alterations).  Bearing this in mind - to perform almost any
> 'special' requirements is about adding an appropriate template that
matches
> the node that is to have special processing and providing the logic that
> handles it.
> So, taking the first requirement - "ensure that <top> is the root node of
> the resulting document" - we need to catch whatever is the current input
> document root element and ensure that <top> is output instead, and then
> continue processing the rest of the document, e.g. adding a template that
> looks like...
>   <xsl:template match="/*">
>     <top>
>       <xsl:apply-templates/>
>     </top>
>   </xsl:template>
> and also ensuring that the <top> element is the document root element in
the
> output.  Well, we have already ensured that <top> is the document root
> element of the output - so we just need to ensure that the <top> element
of
> the input document is not repeated in the output, e.g.
>   <xsl:template match="top">
>     <xsl:apply-templates/>
>   </xsl:template>
>
> Secondly, the requirement "ensure that <maps> mapping data does not appear
> in the resulting document" - again, it is a matter of adding a template
that
> catches this element and prevents it being copied into the output, e.g.
>   <xsl:template match="maps"/>
> (Note that the template tag is self-closing - so although the template
will
> catch the <maps> element it is entirely empty so will do nothing further
> with that element).
>
> So the final stylesheet (hmmm, see also notes on .Net bug below) is as
> follows...
>
> <?xml version="1.0"?>
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
> <xsl:output method="xml" indent="yes"/>
> <xsl:variable name="maps" select="/mapswithdata/maps/element"/>
>
> <xsl:template match="/">
>   <xsl:apply-templates/>
> </xsl:template>
>
> <xsl:template match="*">
>   <xsl:variable name="this-element-map" select="$maps[@source =
> local-name(current())]"/>
>   <xsl:choose>
>     <xsl:when test="$this-element-map">
>       <xsl:element name="{$this-element-map/@target}">
>         <xsl:apply-templates select="@*" mode="mapped">
>           <xsl:with-param name="attributes-map"
> select="$this-element-map/attribute"/>
>         </xsl:apply-templates>
>         <xsl:apply-templates/>
>       </xsl:element>
>     </xsl:when>
>     <xsl:otherwise>
>       <xsl:copy>
>         <xsl:apply-templates select="@* | node()"/>
>       </xsl:copy>
>     </xsl:otherwise>
>   </xsl:choose>
> </xsl:template>
>
> <xsl:template match="/*">
>   <top>
>     <xsl:apply-templates/>
>   </top>
> </xsl:template>
>
> <xsl:template match="top">
>   <xsl:apply-templates/>
> </xsl:template>
>
> <xsl:template match="maps"/>
>
> <xsl:template match="@*" mode="mapped">
>   <xsl:param name="attributes-map"/>
>   <xsl:variable name="this-attribute-map" select="$attributes-map[@source
=
> local-name(current())]"/>
>   <xsl:if test="$this-attribute-map">
>     <xsl:attribute name="{$this-attribute-map/@target}">
>       <xsl:value-of select="."/>
>     </xsl:attribute>
>   </xsl:if>
> </xsl:template>
>
> <xsl:template match="@* | text() | comment() | processing-instruction()">
>   <xsl:copy/>
> </xsl:template>
> </xsl:stylesheet>
>
>
> OK, finally...
>
> > When I test this using saxon or the marrowsoft.com client it works, but
> when
> > I test it with C# System.Xml.Xsl.XslTransform it does not work. Is there
> > some modification that must be done to this to make it work w/ C#
> > System.Xml.Xsl.XslTransform? The part that I think is not getting
> processed
> > by the C# System.Xml.Xsl.XslTransform is <xsl:template match="@*"
> > mode="mapped">
>
> Yes, you are right.  There seems to be a bug in .Net casuing this
stylesheet
> not to work as it would be expected.  I haven't been able to come with
with
> a shorter example that illustrates this bug - and I believe that something
> similar to this was reported recently on one of the newsgroups.  Anyway,
> that is up to MS to determine the problem and get it fixed!  I have even
> tried a few work arounds and all seem to fail with .Net!
>
>
> HTH
> Marrow
> http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger)
> http://www.topxml.com/Xselerator
>
>
>




transparent
Print
Mail
Like It
Disclaimer
.

These Archives are provided for informational purposes only and have been generated directly from the Altova mailing list archive system and are comprised of the lists set forth on www.altova.com/list/index.html. Therefore, Altova does not warrant or guarantee the accuracy, reliability, completeness, usefulness, non-infringement of intellectual property rights, or quality of any content on the Altova Mailing List Archive(s), regardless of who originates that content. You expressly understand and agree that you bear all risks associated with using or relying on that content. Altova will not be liable or responsible in any way for any content posted including, but not limited to, any errors or omissions in content, or for any losses or damage of any kind incurred as a result of the use of or reliance on any content. This disclaimer and limitation on liability is in addition to the disclaimers and limitations contained in the Website Terms of Use and elsewhere on the site.

.
.

transparent

transparent