Re: [xsl] Xslt transform & grouping, Using the Muenchian Method?

Subject: Re: [xsl] Xslt transform & grouping, Using the Muenchian Method?
From: "row.filter" <row.filter@xxxxxxxxx>
Date: Mon, 11 Oct 2004 10:10:32 +0200
ok.

Is this correct?
I got some parent elements (Document) node hanging outside for some reason?

I would like also to filter on two attributes. It this correct
(<xsl:copy-of select="@* | Article[@filter = 'food' or @filter=
'drink']"/>) ?


<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">

  <xsl:template match="/">
  <Documents>
  	<xsl:apply-templates select="Documents/Document[@filter = 'food' or
@filter = '']">
    	<xsl:sort select="@title"/>
  	</xsl:apply-templates>
  </Documents>
  </xsl:template>

  <xsl:template match="/Documents/Document">
    <xsl:copy>
        <xsl:copy-of select="@* | Article[@filter = 'food']"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>





On Mon, 11 Oct 2004 09:19:16 +0200, Anton Triest <anton@xxxxxxxx> wrote:
> row.filter wrote:
> 
> >I get this exception:
> >
> >Exception Details: System.Xml.Xsl.XsltException: 'local-name()' is an
> >invalid QName.
> >
> That's correct, you cannot use expressions in xsl:element name unless
> you enclose them
> in curly braces: <xsl:element name="{local-name()}">
> 
> The next problem will be that every Document in the output will be
> nested inside another
> Document element, because of the <xsl:copy>.
> 
> Infact, <xsl:copy> and <xsl:element name="{local-name()}"> do the same
> thing so you
> only need one of them (or use just <Document> instead).
> 
> The code will also add multiple Document elements at the root level,
> making it invalid XML
> (an XML document should always have one root element). To ensure that
> the output has
> one root node, add <Documents> to the template match="/" (or, if you
> prefer, use
> match="/Documents" and then <xsl:copy>).
> 
> HTH,
> Anton
> 
> 
> 
> >On Sun, 10 Oct 2004 11:27:20 -0700, M. David Peterson
> ><m.david@xxxxxxxxxx> wrote:
> >
> >
> >>I'm not sure if using keys is necessary as it seems they are already grouped
> >>using the document order and hierarchy.  Either way, to ensure that they are
> >>processed numerically if and only if the @filter attribute equals food or has no
> >>value and then further more only include Article elements within each Document
> >>structure that contain the @filter equal to food then your problem is pretty
> >>simple...
> >>
> >><?xml version="1.0"?>
> >><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">
> >><xsl:template match="/">
> >>  <xsl:apply-templates select="Documents/Document[@filter = 'food' or @filter =
> >>'']">
> >>    <xsl:sort select="@title"/>
> >>  </xsl:apply-templates>
> >>  </xsl:template>
> >>  <xsl:template match="Document">
> >>    <xsl:copy>
> >>      <xsl:element name="local-name()">
> >>        <xsl:copy-of select="@* | Article[@filter = 'food']"/>
> >>      </xsl:element>
> >>    </xsl:copy>
> >>  </xsl:template>
> >></xsl:stylesheet>
> >>
> >>Produces this using your sample XML input:
> >>
> >><Document title="1" chapter="1" href="file1.xml" filter="food">
> >>  <Article title="1.1" info="sub" filter="food"/>
> >>  <Article title="1.2" info="main" filter="food"/>
> >></Document>
> >><Document title="3" chapter="3" href="file2.xml" filter=""/>
> >>
> >>If this is not the output you want maybe an example of what you want the output
> >>to look like will help us help you further.
> >>
> >>Best of luck!
> >>
> >><M:D/>
> >>
> >>
> >>
> >>
> >>row.filter wrote:
> >>
> >>
> >>>Hi,
> >>>
> >>>I would like to group following, by attribute Title, and then filter
> >>>by attribute filter="food". Title-attribute exists in both Document
> >>>and Article elements.
> >>>
> >>>That is, groups should be created based on attribute Title in Document
> >>>element, and filtered by attribute e.g. filter="food".
> >>>
> >>>Currently I am using grouping and filtering in following stylesheet.
> >>>
> >>>All other elements, where filter != "food" should be ignored.
> >>>Filter is global parameter.
> >>>
> >>>Thank you!
> >>>
> >>>
> >>>Some help on the way:
> >>>
> >>>XSL:
> >>>
> >>><?xml version='1.0' encoding='UTF-8'?>
> >>>
> >>><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
> >>>
> >>><xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
> >>>
> >>><xsl:key name="by-info" match="Article" use="@info"/>
> >>>
> >>><xsl:param name="filter" select="'food'"/>
> >>>
> >>><xsl:template match="Documents">
> >>>      <Documents>
> >>>              <xsl:for-each select="Document[@filter='' or
> >>>@filter=$filter]/Article[generate-id()=generate-id(key('by-info',@info)[@filter=$filter])]">
> >>>                      <Document name="{@info}">
> >>>                              <xsl:copy-of select="key('by-info',@info)[@filter=$filter]"/>
> >>>                      </Document>
> >>>              </xsl:for-each>
> >>>      </Documents>
> >>></xsl:template>
> >>>
> >>></xsl:stylesheet>
> >>>
> >>>
> >>>XML:
> >>>
> >>><Documents>
> >>>      <Document title="1" chapter="1" href="file1.xml" filter="food">
> >>>              <Article title="1.1" info="sub" filter="food"/>
> >>>              <Article title="1.2" info="main" filter="food"/>
> >>>      </Document>
> >>>      <Document title="2" chapter="2" href="file2.xml" filter="drink">
> >>>              <Article title="2.1" info="sub" filter="drink"/>
> >>>              <Article title="2.2" info="main" filter="food"/>
> >>>      </Document>
> >>>      <Document title="3" chapter="3" href="file2.xml" filter="">
> >>>              <Article title="3.1" info="sub" filter="drink"/>
> >>>              <Article title="3.2" info="child" filter=""/>
> >>>      </Document>
> >>></Documents>
> 
> 


-- 

[row.filter]

Current Thread