[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] FW: Best way to create default elements


Subject: Re: [xsl] FW: Best way to create default elements
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Wed, 21 Aug 2013 21:56:05 +0100

In XSLT 2.0 you can do

<xsl:for-each select="1 to $N">
  <xsl:element name="DIfferentialDiagnosis{$N}">
    ...
  </xsl:element>
</xsl:for-each>

Mind you, I would think twice about working for a client who asks for XML in
such an appalling format!

Michael Kay
Saxonica


On 21 Aug 2013, at 21:45, Rick Quatro wrote:

> Hi,
>
> I got this working, but I want to see if this is the best approach. I have
a
> flat xml file from InDesign similar to this:
>
> <?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's</DifferentialDiagnosis>
>        <DifferentialDiagnosis>Sicker</DifferentialDiagnosis>
>        <DifferentialDiagnosis>Sickest-</DifferentialDiagnosis>
>        <TeachingPoint>Point1</TeachingPoint>
>        <TeachingPoint>Point2</TeachingPoint>
>        <SuggestedReading>Reading1</SuggestedReading>
>        <SuggestedReading>Reading2</SuggestedReading>
>        <Category>Category One: Subcategory</Category>
>        <CaseTitle>Title Two</CaseTitle>
>        <Institution>Title Two</Institution >
>        <Author>Author Two</Author>
>        <History>History Two</History>
>        <DifferentialDiagnosis>Sickly</DifferentialDiagnosis>
>        <DifferentialDiagnosis>Sicklier</DifferentialDiagnosis>
>        <DifferentialDiagnosis>Sickliest</DifferentialDiagnosis>
>        <TeachingPoint>Point1</TeachingPoint>
>        <TeachingPoint>Point2</TeachingPoint>
>        <SuggestedReading>Reading1</SuggestedReading>
>        <SuggestedReading>Reading2</SuggestedReading></Story>
> </Cases>
>
> I need to massage the content for a database. The requirement for
> DifferentialDiagnosis elements is for 20 different elements in the form of
> <DifferentialDiagnosis1>, <DifferentialDiagnosis2>, etc., up to
> <DifferentialDiagnosis20>. The client wants all of the elements present,
> even if they are empty. Here is my output:
>
> <?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's</DifferentialDiagnosis1>
>      <DifferentialDiagnosis2>Sicker</DifferentialDiagnosis2>
>      <DifferentialDiagnosis3>Sickest-</DifferentialDiagnosis3>
>      <DifferentialDiagnosis4/>
>      <DifferentialDiagnosis5/>
>      <DifferentialDiagnosis6/>
>      <DifferentialDiagnosis7/>
>      <DifferentialDiagnosis8/>
>      <DifferentialDiagnosis9/>
>      <DifferentialDiagnosis10/>
>      <DifferentialDiagnosis11/>
>      <DifferentialDiagnosis12/>
>      <DifferentialDiagnosis13/>
>      <DifferentialDiagnosis14/>
>      <DifferentialDiagnosis15/>
>      <DifferentialDiagnosis16/>
>      <DifferentialDiagnosis17/>
>      <DifferentialDiagnosis18/>
>      <DifferentialDiagnosis19/>
>      <DifferentialDiagnosis20/>
>      <TeachingPoint>Point1</TeachingPoint>
>      <TeachingPoint>Point2</TeachingPoint>
>      <SuggestedReading>Reading1</SuggestedReading>
>      <SuggestedReading>Reading2</SuggestedReading>
>   </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>Sickly</DifferentialDiagnosis1>
>      <DifferentialDiagnosis2>Sicklier</DifferentialDiagnosis2>
>      <DifferentialDiagnosis3>Sickliest</DifferentialDiagnosis3>
>      <DifferentialDiagnosis4/>
>      <DifferentialDiagnosis5/>
>      <DifferentialDiagnosis6/>
>      <DifferentialDiagnosis7/>
>      <DifferentialDiagnosis8/>
>      <DifferentialDiagnosis9/>
>      <DifferentialDiagnosis10/>
>      <DifferentialDiagnosis11/>
>      <DifferentialDiagnosis12/>
>      <DifferentialDiagnosis13/>
>      <DifferentialDiagnosis14/>
>      <DifferentialDiagnosis15/>
>      <DifferentialDiagnosis16/>
>      <DifferentialDiagnosis17/>
>      <DifferentialDiagnosis18/>
>      <DifferentialDiagnosis19/>
>      <DifferentialDiagnosis20/>
>      <TeachingPoint>Point1</TeachingPoint>
>      <TeachingPoint>Point2</TeachingPoint>
>      <SuggestedReading>Reading1</SuggestedReading>
>      <SuggestedReading>Reading2</SuggestedReading>
>   </newRecord>
> </data>
>
> Below is my (abbreviated) stylesheet. I used recursion and think that is
the
> best way to do it, but I really want to learn XSLT the right way. If I
> missed a better technique, I want to learn what it is. Thanks for the
> feedback.
>
> <?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" />
>        </data>
>    </xsl:template>
>
>    <xsl:key name="category" match="Story/*[not(self::Category)]"
>        use="generate-id(preceding-sibling::Category[1])"/>
>
>    <xsl:template match="Category">
>        <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="key('category',generate-id(.))"/>
>        </newRecord>
>    </xsl:template>
>
>    <xsl:template match="Story/*" priority="-1">
>        <xsl:copy-of select="." />
>    </xsl:template>
>
>    <xsl:template match="DifferentialDiagnosis">
>
>        <xsl:variable name="diagnosis">
>            <xsl:value-of select="1 +
>                count(preceding-sibling::DifferentialDiagnosis) -
>
count(preceding-sibling::Category[1]/preceding-sibling::DifferentialDiagnosi
> s)"/>
>        </xsl:variable>
>        <xsl:element name="{concat(name(),$diagnosis)}"><xsl:value-of
>            select="."/></xsl:element>
>        <xsl:if
> test="not(following-sibling::*[1][self::DifferentialDiagnosis])">
>            <xsl:call-template name="fillDiagnosis">
>                <xsl:with-param name="no"><xsl:value-of select="2 +
>                    count(preceding-sibling::DifferentialDiagnosis) -
>
count(preceding-sibling::Category[1]/preceding-sibling::DifferentialDiagnosi
> s)"/></xsl:with-param>
>            </xsl:call-template>
>        </xsl:if>
>    </xsl:template>
>
>    <xsl:template name="fillDiagnosis">
>        <xsl:param name="no" />
>        <xsl:choose>
>            <xsl:when test="$no &lt;= 20">
>                <xsl:element name="{concat('DifferentialDiagnosis',$no)}"/>
>                <xsl:call-template name="fillDiagnosis">
>                    <xsl:with-param name="no" select="$no+1" />
>                </xsl:call-template>
>            </xsl:when>
>        </xsl:choose>
>    </xsl:template>
>
> </xsl:stylesheet>
>
> Rick Quatro
> Carmen Publishing Inc.
> 585-283-5045
> rick@xxxxxxxxxxxxxxx


Current Thread
Keywords