RE: [xsl] Manipulating elements depending on the existence of sub-elements

Subject: RE: [xsl] Manipulating elements depending on the existence of sub-elements
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Wed, 12 Mar 2008 15:01:14 -0000
Try something like this:

<xsl:template match="/"
  <xsl:apply-templates select="//UniqueInfo"/>
</xsl:template>

<xsl:template match="UniqueInfo">
  <transaction>
    <xsl:apply-templates
select="../preceding-sibling::transaction[not(UniqueInfo)]/line | ../line"/>
  </transaction>
</xsl:template>

<xsl:template match="line>"
  <line position="{position()}"/>
</xsl:template>

Alternatively, what I often advise people when handling dirty data: write
two transformations and run them in series (a pipeline). The first one is to
clean up the data, the second is to transform it. One benefit is that when
you fix the data supplier to stop generating dirty data, you can throw out
the first stylesheet. Another benefit is that the clean-up stylesheet will
be reusable when you want to process the dirty data in a different way.

Michael Kay
http://www.saxonica.com/  
 

> -----Original Message-----
> From: Adil Ladhani [mailto:dillio@xxxxxxxxx] 
> Sent: 12 March 2008 14:40
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] Manipulating elements depending on the 
> existence of sub-elements
> 
> Hi Wendell,
> 
> Thanks for the response (just as a brief aside, you've 
> already been extremely helpful to me for my current project, 
> as archived posts of yours have been solving almost every 
> issue I've run into thus far). I had actually read several 
> posts regarding the caveats about using position(), but until 
> your response I was still incorrectly assuming that it 
> referred to the current node's position in a tree 
> (representing the current context), rather than a list that 
> may or may not respect the ordering of the document. The 
> numbers were as expected, so I didn't think twice about them.
> 
> Here is what I'm trying to accomplish in regards to the count:
> I have an XML document containing information about 
> Transactions (represented by Transaction elements). Within 
> each Transaction, there are one or more text lines containing 
> its contents (represented by Line elements). Each Transaction 
> also has a UniqueInfo element which specifies its identifying 
> information. For each Transaction, there will be a row 
> inserted into the database for every Line that it contains 
> (along with the unique identifying information). Since the 
> unique identifying information will be the same for every 
> Line in the Transaction (thus the same for every row inserted 
> for a given transaction), I want to add a count for Line 
> number, in order to have a primary key (and to be able to 
> re-create the original document based on the db entries).
> 
> This was all going peachy, but the document being parsed to 
> XML inexplicably decided to be a rebel and become 
> inconsistent with its formatting. This lead to a couple cases 
> where one transaction would be split between two Transaction 
> elements, resulting in something like the following:
> 
> <Transaction>
> <Line> Text Here </Line>
> <Line> More Text </Line>
> </Transaction>
> 
> <Transaction>
> <Line> Text Text Text </Line>
> <Line> qwerty </Line>
> <UniqueInfo>
> <Number> 123 </Number>
> <Name> Bob </Name>
> <Type> 02 </Type>
> </UniqueInfo>
> </Transaction>
> 
> Now that I'm using following-sibling to get the UniqueInfo in 
> these cases, it's okay that the XML is not entirely accurate 
> because the database entry will be... with the exception of 
> line count.
> 
> So basically I want the count to represent the position of a 
> given Line within a given Transaction, and in cases where a 
> UniqueInfo element is not present (i.e. it's a stub of a 
> transaction), I want the line count of that Transaction's 
> following sibling to start where its own line count left off, 
> rather than back at 1 (which is what's happening currently 
> and what should be happening for all other transactions). If 
> this is not possible or more effort than its worth, I'd 
> settle for a line count representing the position of the line 
> in the context of the entire document (so the count just 
> increments with every line). I tried to do the latter by 
> changing the context of position(), but it didn't work out 
> too well so any help would be most appreciated.
> 
> Thanks,
> 
> Adil

Current Thread