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 XSLT Re: Merge two XML docments with XSLTTo: 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 > > > | ||||||
| Company | Legal | Press | Partners | Careers | Sitemap | Contact Us | Altova Blog | Mobile | Full Site | |||
|
