Altova Mailing List Archives>Archive Index >microsoft.public.xsl Archive Home >Recent entries >Thread Prev - Re: Merge two XML docments with XSLT [Thread Next] Re: Merge two XML docments with XSLTTo: NULL Date: 9/30/2004 5:28:00 PM > <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>
What is the purpose of this second </xsl:apply-templates> ?
"Daniel" <softwareengineer98037@y...> wrote in message
news:u9Lm2AcmEHA.1440@T......
> 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
> >
> >
> >
>
>
| ||||||
| Company | Legal | Press | Partners | Careers | Sitemap | Contact Us | Altova Blog | Mobile | Full Site | |||
|
