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

[xsl] FW: Best way to create default elements


Subject: [xsl] FW: Best way to create default elements
From: "Rick Quatro" <rick@xxxxxxxxxxxxxx>
Date: Wed, 21 Aug 2013 16:45:50 -0400

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