|
[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Deepening a flat structure and numbering nodes
Grouping in XSLT 1.0 is best done with keys; this key:
<xsl:key name="records" match="*[not(self::Category)]"
use="generate-id(preceding-sibling::Category[1])"/>
sets a key for any element that is not a <Category> as the id of the
preceding Category element.
Then the grouping can be done according to that key, and so can be the
counting within a "group".
Here's the full stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="xsl">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:key name="records" match="*[not(self::Category)]"
use="generate-id(preceding-sibling::Category[1])"/>
<xsl:template match="/*">
<data>
<xsl:apply-templates select="Story/Category"/>
</data>
</xsl:template>
<xsl:template match="Category">
<xsl:variable name="key" select="generate-id(.)"/>
<newRecord>
<Category>
<xsl:value-of select="substring-before(., ':')"/>
</Category>
<Subcategory>
<xsl:value-of select="normalize-space(substring-after(., ':'))"/>
</Subcategory>
<Case>
<xsl:number/>
</Case>
<xsl:apply-templates select="key('records', $key)">
<xsl:with-param name="key" select="$key"/>
</xsl:apply-templates>
</newRecord>
</xsl:template>
<xsl:template match="*">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="DifferentialDiagnosis">
<xsl:param name="key"/>
<xsl:element name="{concat(name(),
count(preceding-sibling::DifferentialDiagnosis[generate-id(preceding-sibling::Category[1])
= $key]) + 1)}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
This produces the following result:
<data>
<newRecord>
<Category>Category</Category>
<Subcategory>Subcategory</Subcategory>
<Case>1</Case>
<CaseTitle>Title One</CaseTitle>
<Institution>Institution One</Institution>
<Author>Authors One</Author>
<History>History One</History>
<DifferentialDiagnosis1>Sick</DifferentialDiagnosis1>
<DifferentialDiagnosis2>Sicker</DifferentialDiagnosis2>
<DifferentialDiagnosis3>Sickest</DifferentialDiagnosis3>
<TeachingPoint>Point1</TeachingPoint>
<TeachingPoint>Point2</TeachingPoint>
</newRecord>
<newRecord>
<Category>Category One</Category>
<Subcategory>Subcategory</Subcategory>
<Case>2</Case>
<CaseTitle>Title Two</CaseTitle>
<Institution>Title Two</Institution>
<Author>Author Two</Author>
<History>History Two</History>
<DifferentialDiagnosis1>Sick</DifferentialDiagnosis1>
<DifferentialDiagnosis2>Sicker</DifferentialDiagnosis2>
<DifferentialDiagnosis3>Sickest</DifferentialDiagnosis3>
<TeachingPoint>Point1</TeachingPoint>
<TeachingPoint>Point2</TeachingPoint>
</newRecord>
</data>
Hope this helps.
Regards,
EB
On Sat, Aug 10, 2013 at 2:53 PM, Rick Quatro <rick@xxxxxxxxxxxxxx> wrote:
> Hi All,
>
> Here is my input XML:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <Cases>
> <Story>
> <Category>Category: Subcategory</Category>
> <CaseTitle>Title One</CaseTitle>
> <Institution>Institution One</Institution >
> <Author>Authors One</Author>
> <History>History One</History>
> <DifferentialDiagnosis>Sick</DifferentialDiagnosis>
> <DifferentialDiagnosis>Sicker</DifferentialDiagnosis>
> <DifferentialDiagnosis>Sickest</DifferentialDiagnosis>
> <TeachingPoint>Point1</TeachingPoint>
> <TeachingPoint>Point2</TeachingPoint>
> <Category>Category One: Subcategory</Category>
> <CaseTitle>Title Two</CaseTitle>
> <Institution>Title Two</Institution >
> <Author>Author Two</Author>
> <History>History Two</History>
> <DifferentialDiagnosis>Sick</DifferentialDiagnosis>
> <DifferentialDiagnosis>Sicker</DifferentialDiagnosis>
> <DifferentialDiagnosis>Sickest</DifferentialDiagnosis>
> <TeachingPoint>Point1</TeachingPoint>
> <TeachingPoint>Point2</TeachingPoint>
> </Story>
> </Cases>
>
> I want to organize the data in a deeper structure like this:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <data>
> <newRecord>
> <Category>Category</Category>
> <Subcategory>Subcategory</Subcategory>
> <Case>1</Case>
> <CaseTitle>Title One</CaseTitle>
> <Institution>Institution One</Institution>
> <Author>Authors One</Author>
> <History>History One</History>
> <DifferentialDiagnosis>Sick</DifferentialDiagnosis>
> <DifferentialDiagnosis>Sicker</DifferentialDiagnosis>
> <DifferentialDiagnosis>Sickest</DifferentialDiagnosis>
> <TeachingPoint>Point1</TeachingPoint>
> <TeachingPoint>Point2</TeachingPoint>
> </newRecord>
> <newRecord>
> <Category>Category One</Category>
> <Subcategory>Subcategory</Subcategory>
> <Case>2</Case>
> <CaseTitle>Title Two</CaseTitle>
> <Institution>Title Two</Institution>
> <Author>Author Two</Author>
> <History>History Two</History>
> <DifferentialDiagnosis>Sick</DifferentialDiagnosis>
> <DifferentialDiagnosis>Sicker</DifferentialDiagnosis>
> <DifferentialDiagnosis>Sickest</DifferentialDiagnosis>
> <TeachingPoint>Point1</TeachingPoint>
> <TeachingPoint>Point2</TeachingPoint>
> </newRecord>
> </data>
>
> With help from the list, I am using this to get the results.
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
>
> <xsl:output indent="yes" />
>
> <xsl:template match="Cases/Story">
> <data>
> <xsl:apply-templates select="Category[1]" />
> </data>
> </xsl:template>
>
> <xsl:template match="Category">
> <xsl:element name="newRecord">
> <Category><xsl:value-of select="substring-before(.,':
> ')"/></Category>
> <Subcategory><xsl:value-of select="substring-after(.,':
> ')"/></Subcategory>
> <Case><xsl:number count="Category"/></Case>
> <xsl:apply-templates
> select="following-sibling::*[1][not(self::Category)]"
> mode="in-case-siblings"/>
> </xsl:element>
> <xsl:apply-templates select="following-sibling::Category[1]"/>
> </xsl:template>
>
> <xsl:template match="*" mode="in-case-siblings">
> <xsl:copy-of select="." />
> <xsl:apply-templates
> select="following-sibling::*[1][not(self::Category)]"
> mode="in-case-siblings"/>
> </xsl:template>
>
> <xsl:template match="Category" mode="in-case-siblings"/>
>
> </xsl:stylesheet>
>
> This is working well, but now I need to do something different to the
> <DifferentialDiagnosis> elements. I want to change the element names by
> numbering them sequentially within my <newRecord> element, like this:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <data>
> <newRecord>
> <Category>Category</Category>
> <Subcategory>Subcategory</Subcategory>
> <Case>1</Case>
> <CaseTitle>Title One</CaseTitle>
> <Institution>Institution One</Institution>
> <Author>Authors One</Author>
> <History>History One</History>
> <DifferentialDiagnosis1>Sick</DifferentialDiagnosis1>
> <DifferentialDiagnosis2>Sicker</DifferentialDiagnosis2>
> <DifferentialDiagnosis3>Sickest</DifferentialDiagnosis3>
> <TeachingPoint>Point1</TeachingPoint>
> <TeachingPoint>Point2</TeachingPoint>
> </newRecord>
> <newRecord>
> <Category>Category One</Category>
> <Subcategory>Subcategory</Subcategory>
> <Case>2</Case>
> <CaseTitle>Title Two</CaseTitle>
> <Institution>Title Two</Institution>
> <Author>Author Two</Author>
> <History>History Two</History>
> <DifferentialDiagnosis1>Sick</DifferentialDiagnosis1>
> <DifferentialDiagnosis2>Sicker</DifferentialDiagnosis2>
> <DifferentialDiagnosis3>Sickest</DifferentialDiagnosis3>
> <TeachingPoint>Point1</TeachingPoint>
> <TeachingPoint>Point2</TeachingPoint>
> </newRecord>
> </data>
>
> I added this rule to my stylesheet:
>
> <xsl:template match="DifferentialDiagnosis" mode="in-case-siblings">
> <xsl:variable name="diagnosis"><xsl:number
> count="DifferentialDiagnosis" from="Category"/></xsl:variable>
> <xsl:element name="{concat(name(),$diagnosis)}"><xsl:value-of
> select="."/></xsl:element>
> <xsl:apply-templates
> select="following-sibling::*[1][not(self::Category)]"
> mode="in-case-siblings"/>
> </xsl:template>
>
> This basically "works" except the numbers are sequential throughout the
> document.
>
> <data>
> <newRecord>
> ...
> <DifferentialDiagnosis1>Sick</DifferentialDiagnosis1>
> <DifferentialDiagnosis2>Sicker</DifferentialDiagnosis2>
> <DifferentialDiagnosis3>Sickest</DifferentialDiagnosis3>
> ...
> </newRecord>
> <newRecord>
> ...
> <DifferentialDiagnosis1>Sick</DifferentialDiagnosis5>
> <DifferentialDiagnosis2>Sicker</DifferentialDiagnosis6>
> <DifferentialDiagnosis3>Sickest</DifferentialDiagnosis7>
> ...
> </newRecord>
> </data>
>
> I need the numbers to reset for each <newRecord> element. I am sorry for the
> long post, but I want to be complete as possible. Also, for this project, I
> need to use XSLT 1.0. Thank you very much.
>
> Rick
|
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
|

Cart








