将XML转换为多个HTML表

时间:2014-04-23 18:41:48

标签: html xml xslt

我有一个需要转到HTML的XML文件。它将被转换为多个表,每个表有16行,包括第一行XML数据成为每个表的第一行。每个表都会获得一个唯一的ID。

xml示例文件的结构如下(截断 - 通常为几百行):

<?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>

根据示例文件,生成的HTML文件应如下所示(显然,较大的XML文件会导致更多表):

<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>

基于将XML转换为表的其他几个实例,我假设我需要利用XSLT来实现这一目标。我遇到的问题是我永远无法将字段和字段拆分成单独的元素,同时仍然可以使表格的其余部分正确生成。它可以是一个大表,也可以是几个表,每行只有一个元素。

编辑:

以下XSLT为我提供了一个格式正确的大表。我只是不确定如何将其转换为几个16行表:

<?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>

我非常感谢这项努力中的任何帮助。

2 个答案:

答案 0 :(得分:1)

这是一个不使用DOE(disable-output-escaping="yes")的选项。

可能有一个更好/更有效的解决方案,但我主要使用XSLT 2.0,其中分组更容易。

XML输入

<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>

<强>输出

<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>

答案 1 :(得分:0)

我似乎误读了你的问题。我首先想到你的XML也分成了16个多组,但是现在我再看一遍它是不是。你的问题很难,我也不知道一个很好的解决方案。我一直在做的就是注入<some_tags>,如下所示:

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

所以你能做的就是:

<?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>