[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Element selection based on different overlapping
On 2/1/06, Trevor Nicholls <trevor@xxxxxxxxxxxxxxxxxx> wrote: > Hello > > I am transforming some poorly designed XML files into documents which > conform to a relatively simple schema. One of the decisions I need to make > involves an element called <TABLE>. There are literally thousands of tables > in my input and literally hundreds of different element types which may be > descendants of tables (these are nothing like HTML tables!) However certain > specific table types are discernable based on the family of elements they > contain, i.e. I can define a set M of element names and if every descendant > of a particular <TABLE> is in this set then it is an M-TABLE, I can define > another set N to identify any N-TABLE, and so on. Individual elements may > appear in more than one set, individual tables may not. > > What I am struggling with is how to define this condition in an Xpath. I > know how to identify any <TABLE> that contains a <Cell> descendant, but > <Cell> elements may be in more than one table type - it depends on what > other descendants I can find. Similarly I can identify any <TABLE> that does > NOT contain a <Side> descendant, but again there are multiple table types > that lack a <Side>. > > A very simple case can be coded in the following XSL fragment to illustrate > what I mean: > > <xsl:template match="TABLE"> > <xsl:variable name="descs" select="count(descendant::*)" /> > <xsl:variable name="tabx" select="count(descendant::ROW | descendant::CELL | > descendant::A | descendant::CODE | descendant::TYPING)" /> > <xsl:choose> > <xsl:when test="$descs=$tabx"><xsl:call-template name="tableX" > /></xsl:when> > <xsl:otherwise><xsl:call-template name="tableOther" > /></xsl:otherwise> > </xsl:choose> > </xsl:template> > > This works - and would be quite acceptable if I was choosing between two > types of table and only had half a dozen element names to compare - but it > doesn't scale very well! > > My question: is there a "manageably" concise expression that will let me > test whether each and every descendant element of the context element is a > member of a particular set of element names? And similarly (in case this is > more appropriate for certain types) is there an analogous expression that > will let me test whether none of the descendant elements of the context > element may be found in a particular set? > > Sorry, I've been struggling with this for several hours and can't find the > sort of thing I'm after in the FAQ either. Define each known table type as a key: <xsl:key name="m-table" match="table[.//ROW][.//CELL][.//A]" use="generate-id()"/> <xsl:key name="n-table" match="table[.//TYPING][.//CODE]" use="generate-id()"/> The m-table key then contains all the tables that fit the description of an "M table", as so on. Then when you process each <TABLE> element, you can easily check what type of table it is: <xsl:template match="TABLE"> <xsl:choose> <xsl:when test="key(m-table, generate-id())"> I'm an m-table </xsk:when> <xsl:when test="key(n-table, generate-id())"> I'm an n-table </xsk:when> cheers andrew
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|