0

I have an XML file that needs to go to HTML. It will be converted into several tables with a 16 rows per table, including the first row of XML data becoming the same first row of each table. Each table would get a unique ID.

The xml sample file is structured as follows (truncated - usually several hundred rows):

<?xml version="1.0" encoding="ISO-8859-1"?>
<Data>
<Head><Title>As of April 17, 2014</Title></Head>
<Person><Name>ADAMS,MARTIN</Name><DOB>DOB: 11/02/38</DOB></Person>
<Person><Name>ADAMS,ICHAEL</Name><DOB>DOB: 04/06/37</DOB></Person>
<Person><Name>ALANIZ, ALEX</Name><DOB>DOB: 08/09/37</DOB></Person>
<Person><Name>ALFORD JASON</Name><DOB>DOB: 08/11/35</DOB></Person>
<Person><Name>ALLEGR ERICK</Name><DOB>DOB: 09/01/38</DOB></Person>
<Person><Name>ALMER,XANDER</Name><DOB>DOB: 01/09/33</DOB></Person>
<Person><Name>ALVAREHECTOR</Name><DOB>DOB: 07/04/30</DOB></Person>
<Person><Name>AMAR,  TUMAA</Name><DOB>DOB: 07/09/32</DOB></Person>
<Person><Name>ANON, JUSTIN</Name><DOB>DOB: 05/06/37</DOB></Person>
<Person><Name>ANSON, TERRY</Name><DOB>DOB: 01/18/35</DOB></Person>
<Person><Name>APGUI, JORGE</Name><DOB>DOB: 12/05/34</DOB></Person>
<Person><Name>APDACA, CODY</Name><DOB>DOB: 02/01/33</DOB></Person>
<Person><Name>ARLLO, MARIO</Name><DOB>DOB: 04/03/30</DOB></Person>
<Person><Name>AR, CHANELLE</Name><DOB>DOB: 06/07/39</DOB></Person>
<Person><Name>AR AGA, ADAN</Name><DOB>DOB: 08/30/32</DOB></Person>
<Person><Name>ATC, MICHAEL</Name><DOB>DOB: 05/01/37</DOB></Person>
<Person><Name>BAI Y, JAMES</Name><DOB>DOB: 03/05/35</DOB></Person>
<Person><Name>BAKER, ALECD</Name><DOB>DOB: 02/02/31</DOB></Person>
<Person><Name>BALDWIN , PH</Name><DOB>DOB: 08/08/39</DOB></Person>
<Person><Name>BALLWEBE RRY</Name><DOB>DOB: 04/06/34</DOB></Person>
<Person><Name>BANDLE, T X2</Name><DOB>DOB: 02/09/30</DOB></Person>
</Data>

Based on the sample file, the resulting HTML file should appear as follows (obviously a larger XML file would result in more tables):

<html>
<body>
<table ID="1">
<tr><td colspan="2">Date of list: 04/21/2014</td></tr>
<tr><td>ADAMS,MARTIN</td><td>DOB: 11/02/38</td></tr>
<tr><td>ADAMS,ICHAEL</td><td>DOB: 04/06/37</td></tr>
<tr><td>ALANIZ, ALEX</td><td>DOB: 08/09/37</td></tr>
<tr><td>ALFORD JASON</td><td>DOB: 08/11/35</td></tr>
<tr><td>ALLEGR ERICK</td><td>DOB: 09/01/38</td></tr>
<tr><td>ALMER,XANDER</td><td>DOB: 01/09/33</td></tr>
<tr><td>ALVAREHECTOR</td><td>DOB: 07/04/30</td></tr>
<tr><td>AMAR,  TUMAA</td><td>DOB: 07/09/32</td></tr>
<tr><td>ANON, JUSTIN</td><td>DOB: 05/06/37</td></tr>
<tr><td>ANSON, TERRY</td><td>DOB: 01/18/35</td></tr>
<tr><td>APGUI, JORGE</td><td>DOB: 12/05/34</td></tr>
<tr><td>APDACA, CODY</td><td>DOB: 02/01/33</td></tr>
<tr><td>ARLLO, MARIO</td><td>DOB: 04/03/30</td></tr>
<tr><td>AR, CHANELLE</td><td>DOB: 06/07/39</td></tr>
<tr><td>AR AGA, ADAN</td><td>DOB: 08/30/32</td></tr>
</table>
<table ID="2">
<tr><td colspan="2">Date of list: 04/21/2014</td></tr>
<tr><td>ATC, MICHAEL</td><td>DOB: 05/01/37</td></tr>
<tr><td>BAI Y, JAMES</td><td>DOB: 03/05/35</td></tr>
<tr><td>BAKER, ALECD</td><td>DOB: 02/02/31</td></tr>
<tr><td>BALDWIN , PH</td><td>DOB: 08/08/39</td></tr>
<tr><td>BALLWEBE RRY</td><td>DOB: 04/06/34</td></tr>
<tr><td>BANDLE, T X2</td><td>DOB: 02/09/30</td></tr>
</table>
</body>
</html>

Based on several other instances of converting the XML into tables, I assume I need to utilize XSLT to accomplish this. The problem I've ran into was I could never break up the and fields into separate elements whilst still getting the rest of the table to generate properly. It was either one large table, or several tables with only one element per row.

Edit:

The following XSLT gets me one large table that's formatted properly. I'm just not sure how to get this to several 16 row tables instead:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<table id="1">
<tr><td colspan="2" align="center"><h2><xsl:value-of select="Data/Head/Title"/></h2></td></tr>
<xsl:for-each select="Data/Person">
<tr>
<td><xsl:value-of select="Name"/></td>
<td><xsl:value-of select="DOB"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

I greatly appreciate any assistance in this endeavor.

3
  • See my answer below. If you want more help, show your current xslt that gives you the one large table Commented Apr 23, 2014 at 18:54
  • I've edited my post to add in the XSLT that gives me one large table. Commented Apr 23, 2014 at 19:41
  • I edited my answer to suit your needs. Commented Apr 23, 2014 at 21:24

2 Answers 2

1

Here's an option that doesn't use DOE (disable-output-escaping="yes").

There might be a better/more efficient solution, but I primarily use XSLT 2.0 where grouping is much easier.

XML Input

<Data>
    <Head><Title>As of April 17, 2014</Title></Head>
    <Person><Name>ADAMS,MARTIN</Name><DOB>DOB: 11/02/38</DOB></Person>
    <Person><Name>ADAMS,ICHAEL</Name><DOB>DOB: 04/06/37</DOB></Person>
    <Person><Name>ALANIZ, ALEX</Name><DOB>DOB: 08/09/37</DOB></Person>
    <Person><Name>ALFORD JASON</Name><DOB>DOB: 08/11/35</DOB></Person>
    <Person><Name>ALLEGR ERICK</Name><DOB>DOB: 09/01/38</DOB></Person>
    <Person><Name>ALMER,XANDER</Name><DOB>DOB: 01/09/33</DOB></Person>
    <Person><Name>ALVAREHECTOR</Name><DOB>DOB: 07/04/30</DOB></Person>
    <Person><Name>AMAR,  TUMAA</Name><DOB>DOB: 07/09/32</DOB></Person>
    <Person><Name>ANON, JUSTIN</Name><DOB>DOB: 05/06/37</DOB></Person>
    <Person><Name>ANSON, TERRY</Name><DOB>DOB: 01/18/35</DOB></Person>
    <Person><Name>APGUI, JORGE</Name><DOB>DOB: 12/05/34</DOB></Person>
    <Person><Name>APDACA, CODY</Name><DOB>DOB: 02/01/33</DOB></Person>
    <Person><Name>ARLLO, MARIO</Name><DOB>DOB: 04/03/30</DOB></Person>
    <Person><Name>AR, CHANELLE</Name><DOB>DOB: 06/07/39</DOB></Person>
    <Person><Name>AR AGA, ADAN</Name><DOB>DOB: 08/30/32</DOB></Person>
    <Person><Name>ATC, MICHAEL</Name><DOB>DOB: 05/01/37</DOB></Person>
    <Person><Name>BAI Y, JAMES</Name><DOB>DOB: 03/05/35</DOB></Person>
    <Person><Name>BAKER, ALECD</Name><DOB>DOB: 02/02/31</DOB></Person>
    <Person><Name>BALDWIN , PH</Name><DOB>DOB: 08/08/39</DOB></Person>
    <Person><Name>BALLWEBE RRY</Name><DOB>DOB: 04/06/34</DOB></Person>
    <Person><Name>BANDLE, T X2</Name><DOB>DOB: 02/09/30</DOB></Person>
</Data>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="title" select="/Data/Head/Title"/>

    <xsl:template match="/*">
        <html>
            <body>
                <xsl:apply-templates select="Person"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="Person[position() mod 16 = 1]">
        <table id="{count(preceding-sibling::Person[position() mod 16 = 1])+1}">
            <tr>
                <td colspan="2" align="center">
                    <h2>
                        <xsl:value-of select="$title"/>
                    </h2>
                </td>
            </tr>
            <xsl:apply-templates select=".|following-sibling::Person[not(position() > 15)]" mode="row"/>
        </table>
    </xsl:template>

    <xsl:template match="Person" mode="row">
        <tr>
            <td>
                <xsl:value-of select="Name"/>
            </td>
            <td>
                <xsl:value-of select="DOB"/>
            </td>
        </tr>
    </xsl:template>

    <xsl:template match="text()"/>

</xsl:stylesheet>

Output

<html>
   <body>
      <table id="1">
         <tr>
            <td colspan="2" align="center">
               <h2>As of April 17, 2014</h2>
            </td>
         </tr>
         <tr>
            <td>ADAMS,MARTIN</td>
            <td>DOB: 11/02/38</td>
         </tr>
         <tr>
            <td>ADAMS,ICHAEL</td>
            <td>DOB: 04/06/37</td>
         </tr>
         <tr>
            <td>ALANIZ, ALEX</td>
            <td>DOB: 08/09/37</td>
         </tr>
         <tr>
            <td>ALFORD JASON</td>
            <td>DOB: 08/11/35</td>
         </tr>
         <tr>
            <td>ALLEGR ERICK</td>
            <td>DOB: 09/01/38</td>
         </tr>
         <tr>
            <td>ALMER,XANDER</td>
            <td>DOB: 01/09/33</td>
         </tr>
         <tr>
            <td>ALVAREHECTOR</td>
            <td>DOB: 07/04/30</td>
         </tr>
         <tr>
            <td>AMAR,  TUMAA</td>
            <td>DOB: 07/09/32</td>
         </tr>
         <tr>
            <td>ANON, JUSTIN</td>
            <td>DOB: 05/06/37</td>
         </tr>
         <tr>
            <td>ANSON, TERRY</td>
            <td>DOB: 01/18/35</td>
         </tr>
         <tr>
            <td>APGUI, JORGE</td>
            <td>DOB: 12/05/34</td>
         </tr>
         <tr>
            <td>APDACA, CODY</td>
            <td>DOB: 02/01/33</td>
         </tr>
         <tr>
            <td>ARLLO, MARIO</td>
            <td>DOB: 04/03/30</td>
         </tr>
         <tr>
            <td>AR, CHANELLE</td>
            <td>DOB: 06/07/39</td>
         </tr>
         <tr>
            <td>AR AGA, ADAN</td>
            <td>DOB: 08/30/32</td>
         </tr>
         <tr>
            <td>ATC, MICHAEL</td>
            <td>DOB: 05/01/37</td>
         </tr>
      </table>
      <table id="2">
         <tr>
            <td colspan="2" align="center">
               <h2>As of April 17, 2014</h2>
            </td>
         </tr>
         <tr>
            <td>BAI Y, JAMES</td>
            <td>DOB: 03/05/35</td>
         </tr>
         <tr>
            <td>BAKER, ALECD</td>
            <td>DOB: 02/02/31</td>
         </tr>
         <tr>
            <td>BALDWIN , PH</td>
            <td>DOB: 08/08/39</td>
         </tr>
         <tr>
            <td>BALLWEBE RRY</td>
            <td>DOB: 04/06/34</td>
         </tr>
         <tr>
            <td>BANDLE, T X2</td>
            <td>DOB: 02/09/30</td>
         </tr>
      </table>
   </body>
</html>
Sign up to request clarification or add additional context in comments.

Comments

0

I appear to have mis-read your question. I first thought your XML was also split up in multiple groups of 16, but now that I look again it isn't. Your question is a tough one, and I don't know of a nice solution. What I always do is just inject <some_tags> in, like this:

<xsl:text disable-output-escaping="yes"><![CDATA[<some_tags>]]></xsl:text>

So what you could do is this:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <body>
                <xsl:for-each select="Data/Person">
                    <xsl:if test="(position() mod 16) = 1">
                        <xsl:text disable-output-escaping="yes"><![CDATA[<table id="]]></xsl:text>
                        <xsl:value-of select="(position() + 15) div 16"/>
                        <xsl:text disable-output-escaping="yes"><![CDATA[">]]></xsl:text>
                        <tr><td colspan="2" align="center"><h2><xsl:value-of select="/Data/Head/Title"/></h2></td></tr>
                    </xsl:if>
                    <tr>
                        <td><xsl:value-of select="Name"/></td>
                        <td><xsl:value-of select="DOB"/></td>
                    </tr>
                    <xsl:if test="(position() mod 16) = 0 or position() = last()">
                        <xsl:text disable-output-escaping="yes"><![CDATA[</table>]]></xsl:text>
                    </xsl:if>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

8 Comments

Except in extreme cases (which this isn't) I would never suggest building structured output using DOE.
@DanielHaley so how would you do it? I'm curious too. Or would you rather resort to apply-templates ? Then I really prefer DOE
@nl-x - I added an XSLT 1.0 answer. It's even easier in 2.0.
Also, it's not "resorting" to apply-templates; apply-templates are preferred to xsl:for-each. If you prefer xsl:for-each and DOE, I'm not sure if you really understand how XSLT is meant to work.
@DanielHaley : not taking it personal or anything. But I really do prefer my solution over yours, for the compactness and maintainability. Your solution is quite long and not easily readable. (That's the reason I called it resort to apply-templates) Plus I might even think my code would be more resource-efficient, albeit it is a hack.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.