John
John

Reputation: 285

Formatting xsl for xml

I am trying to get my xsl file just right but I'm having some issues. This is the xml that I'm working with:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<ExportedData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Header>
    <StartDate>2015-02-02T00:00:00</StartDate>
    <EndDate>2015-03-04T23:59:00</EndDate>
    <RecordCount>4</RecordCount>
    <Client />
    <DocumentCount>0</DocumentCount>
  </Header>
  <Applicants>
    <Applicant>
      <ApplicantId>2176</ApplicantId>
      <ModuleTypeId>1</ModuleTypeId>
      <ApplicantInfo>
        <Applications>
          <Application>
            <ApplicationId>6177</ApplicationId>
            <Fields>
              <Field>
                <FieldName>Action Status</FieldName>
                <FieldText>Submitted</FieldText>
              </Field>
              <Field>
                <FieldName>BGCheck Result</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Date Hired</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Location Code</FieldName>
                <FieldText>ManNY</FieldText>
              </Field>
            </Fields>
          </Application>
        </Applications>
      </ApplicantInfo>
      <ApplicantActionDocsInfo />
      <ApplicantFormsInfo />
      <ApplicantActionsInfo />
    </Applicant>
    <Applicant>
      <ApplicantId>2180</ApplicantId>
      <ModuleTypeId>1</ModuleTypeId>
      <ApplicantInfo>
        <Applications>
          <Application>
            <ApplicationId>6181</ApplicationId>
            <Fields>
              <Field>
                <FieldName>Action Status</FieldName>
                <FieldText>Submitted</FieldText>
              </Field>
              <Field>
                <FieldName>BGCheck Result</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Date Hired</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Location Code</FieldName>
                <FieldText>Test0701</FieldText>
              </Field>
            </Fields>
          </Application>
        </Applications>
      </ApplicantInfo>
      <ApplicantActionDocsInfo />
      <ApplicantFormsInfo />
      <ApplicantActionsInfo />
    </Applicant>
    <Applicant>
      <ApplicantId>2193</ApplicantId>
      <ModuleTypeId>1</ModuleTypeId>
      <ApplicantInfo>
        <Applications>
          <Application>
            <ApplicationId>6160</ApplicationId>
            <Fields>
              <Field>
                <FieldName>Action Status</FieldName>
                <FieldText>Submitted</FieldText>
              </Field>
              <Field>
                <FieldName>BGCheck Result</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Date Hired</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Location Code</FieldName>
                <FieldText>00 Demo</FieldText>
              </Field>
            </Fields>
          </Application>
          <Application>
            <ApplicationId>6170</ApplicationId>
            <Fields>
              <Field>
                <FieldName>Action Status</FieldName>
                <FieldText>Submitted</FieldText>
              </Field>
              <Field>
                <FieldName>BGCheck Result</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Date Hired</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Location Code</FieldName>
                <FieldText>00 Demo</FieldText>
              </Field>
            </Fields>
          </Application>
          <Application>
            <ApplicationId>6172</ApplicationId>
            <Fields>
              <Field>
                <FieldName>Action Status</FieldName>
                <FieldText>Submitted</FieldText>
              </Field>
              <Field>
                <FieldName>BGCheck Result</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Date Hired</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Location Code</FieldName>
                <FieldText>00 Demo</FieldText>
              </Field>
            </Fields>
          </Application>
        </Applications>
      </ApplicantInfo>
      <ApplicantActionDocsInfo />
      <ApplicantFormsInfo />
      <ApplicantActionsInfo />
    </Applicant>
    <Applicant>
      <ApplicantId>2196</ApplicantId>
      <ModuleTypeId>1</ModuleTypeId>
      <ApplicantInfo>
        <Applications>
          <Application>
            <ApplicationId>6184</ApplicationId>
            <Fields>
              <Field>
                <FieldName>Action Status</FieldName>
                <FieldText>Submitted</FieldText>
              </Field>
              <Field>
                <FieldName>BGCheck Result</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Date Hired</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Location Code</FieldName>
                <FieldText>Test0701</FieldText>
              </Field>
            </Fields>
          </Application>
          <Application>
            <ApplicationId>6186</ApplicationId>
            <Fields>
              <Field>
                <FieldName>Action Status</FieldName>
                <FieldText>Submitted</FieldText>
              </Field>
              <Field>
                <FieldName>BGCheck Result</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Date Hired</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Location Code</FieldName>
                <FieldText>Test0701</FieldText>
              </Field>
            </Fields>
          </Application>
          <Application>
            <ApplicationId>6188</ApplicationId>
            <Fields>
              <Field>
                <FieldName>Action Status</FieldName>
                <FieldText>Submitted</FieldText>
              </Field>
              <Field>
                <FieldName>BGCheck Result</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Date Hired</FieldName>
                <FieldText />
              </Field>
              <Field>
                <FieldName>Location Code</FieldName>
                <FieldText>Test0701</FieldText>
              </Field>
            </Fields>
          </Application>
        </Applications>
      </ApplicantInfo>
      <ApplicantActionDocsInfo />
      <ApplicantFormsInfo />
      <ApplicantActionsInfo />
    </Applicant>
  </Applicants>
</ExportedData>

As you can see there are 4 main Applicants but within each Applicant there are child elements within the ApplicantInfo. How do I format the multiple child elements to correlate with the 4 main Applicants to fit within a table? Ideally I'd want an additional row for each child element but I don't quite have a handle on that.

Here is the current xsl file that I have:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <!-- match root - build html elements -->
    <xsl:template match="/">
        <html>
            <body>
                <xsl:apply-templates/>
            </body>
        </html>
    </xsl:template>

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

    <!-- Do nothing for the header -->
    <xsl:template match="Header"/>

    <!-- Build table for applicants -->
    <xsl:template match="Applicants">
        <h2>Applicants Info</h2>
        <table border="1">
            <tr bgcolor="#9acd32">
                <th>ApplicantId</th>
                <th>ModuleTypeId</th>
                <th>ApplicantInfo</th>
            </tr>
            <xsl:apply-templates/>
        </table>
    </xsl:template>

    <!-- for each applicant create a table row -->
    <xsl:template match="Applicant">
        <tr>
            <xsl:apply-templates/>
        </tr>
    </xsl:template>

    <!-- for each Applicant/ApplicantId generate table cell -->
    <xsl:template match="ApplicantId">
        <td>
            <xsl:apply-templates/>
        </td>
    </xsl:template>

    <xsl:template match="ModuleTypeId">
        <td>
            <xsl:apply-templates/>
        </td>
    </xsl:template>

    <xsl:template match="ApplicantInfo">
        <td>
            <xsl:apply-templates/>
        </td>
    </xsl:template>

    <xsl:template match="ApplicantActionDocsInfo">
        <td>
            <xsl:apply-templates/>
        </td>
    </xsl:template>

    <xsl:template match="ApplicantFormsInfo">
        <td>
            <xsl:apply-templates/>
        </td>
    </xsl:template>

    <xsl:template match="ApplicantActionsInfo">
        <td>
            <xsl:apply-templates/>
        </td>
    </xsl:template>


    <!-- you probably will want to add more stuff to the table, use templates to do so.-->  
    <!--<xsl:template match="ModuleTypeId | ApplicantInfo | ApplicantActionDocsInfo | ApplicantFormsInfo | ApplicantActionsInfo"/>-->

</xsl:stylesheet>

Again, it displays the 4 main ApplicantIds correctly, but the multiple child elements aren't displaying correctly in the table. How can I generate the additional rows to make this happen?

UPDATE:

My output is currently like this: https://i.sstatic.net/0uD1l.png

I want it to be something like this: https://i.sstatic.net/3Eydl.png

Upvotes: 1

Views: 58

Answers (2)

Mads Hansen
Mads Hansen

Reputation: 66714

Assuming that you want to add additional colums for some of the other elements, this shows how you can do so with generic matches and use of @mode to generate different content for the header columns.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <!-- match root - build html elements -->
    <xsl:template match="/">
        <html>
            <body>
                <xsl:apply-templates select="ExportedData/Applicants"/>
            </body>
        </html>
    </xsl:template>

    <!-- Build table for applicants -->
    <xsl:template match="Applicants">
        <h2>Applicants Info</h2>
        <table border="1">
            <tr bgcolor="#9acd32">
                <xsl:apply-templates select="Applicant[1]/*" mode="header"/>
            </tr>
            <xsl:apply-templates select="Applicant/ApplicantInfo/Applications/Application"/>
        </table>
    </xsl:template>

    <!--Either add more specific elements, or change to * if you want headers for each of the Applicant child elements-->
    <xsl:template match="ApplicantId | ModuleTypeId | ApplicantInfo" mode="header">
        <th><xsl:value-of select="local-name()"/></th>
    </xsl:template>

    <!-- for each application create a table row -->
    <xsl:template match="Application">
        <tr>
            <xsl:apply-templates select="ancestor::ApplicantInfo/preceding-sibling::*"/>
            <td><xsl:apply-templates/></td>
            <!--uncomment below, if you want to add colums for the elements after ApplicantInfo, such as ApplicantActionDocsInfoo, ApplicantFormsInfo, ApplicatnActionsInfo-->
            <!--<xsl:apply-templates select="ancestor::ApplicantInfo/following-sibling::*"/>-->
        </tr>
    </xsl:template>

    <!-- for each Applicant child element generate table cell -->
    <xsl:template match="Applicant/*">
        <td>
            <xsl:apply-templates/>
        </td>
    </xsl:template>

</xsl:stylesheet>

Upvotes: 0

michael.hor257k
michael.hor257k

Reputation: 116959

I want there to be a row for each ApplicationId

If so, you should not be creating a row for each Applicant, but rather for each Application. I also don't see why you need such a forest of templates - it's practically unmanageable.

Try instead:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/">
    <html>
        <body>
            <h2>Applicants Info</h2>
            <table border="1">
            <tr bgcolor="#9acd32">
                <th>ApplicantId</th>
                <th>ModuleTypeId</th>
                <th>ApplicantInfo</th>
            </tr>
                <xsl:apply-templates select="ExportedData/Applicants/Applicant/ApplicantInfo/Applications/Application"/>
            </table>
        </body>
    </html>
</xsl:template>

<xsl:template match="Application">
    <tr>
        <td>
            <xsl:value-of select="ancestor::Applicant/ApplicantId"/>
        </td>
        <td>
            <xsl:value-of select="ancestor::Applicant/ModuleTypeId"/>
        </td>
        <td>
            <xsl:value-of select="."/>
        </td>
    </tr>
</xsl:template>

</xsl:stylesheet>

Result (rendered) when applied to your input:

enter image description here

Of course the labels Applicants Info are a misnomer: it's actually Application Info.

Upvotes: 1

Related Questions