用于动态嵌套XML表的XSLT

时间:2014-06-25 09:35:12

标签: xml xslt xsl-stylesheet

我是xslt的新手,因为我已经动态生成了一个xml文件(即节点名称未知)而面临问题 并尝试了许多使用xslt在html文件中查看嵌套表中内容的方法,但我所有的努力都失败了。

<?xml version="1.0" encoding="UTF-8"?>
<content>
    <Source>
        <Column1>Name</Column1>
        <Column2>Organization Name</Column2>
        <SubSource>
            <Column1>Name</Column1>
            <Column2>Person Name</Column2>
            <Column1>Address</Column1>
            <Column2>House: E5, Block-G, Road-02</Column2>
            <Details>
                <Column1>Entry date</Column1>
                <Column2>6/6/13 12:04 PM</Column2>
                <Column1>height</Column1>
                <Column2>153</Column2>
                <Column1>weight</Column1>
                <Column2>53.5</Column2>
                <Column1>temperature</Column1>
                <Column2>98.67</Column2>
                <Column1>pulse rate</Column1>
                <Column2>76</Column2>
                <Advices>
                    <Advice>
                        <Column1>Title</Column1>
                        <Column2>Workout</Column2>
                        <Column1>Location</Column1>
                        <Column2>In the Park</Column2>
                    </Advice>
                    <Advice>
                        <Column1>Title</Column1>
                        <Column2>Eating Habit</Column2>
                        <Column1>Remarks</Column1>
                        <Column2>Eat Less</Column2>
                        <Column1>Notes</Column1>
                        <Column2>Avoid salts</Column2>
                    </Advice>
                </Advices>
            </Details>
        </SubSource>
    </Source>
    <Source>
        <Column1>Name</Column1>
        <Column2>Organization Name</Column2>
        <SubSource>
            <Column1>Name</Column1>
            <Column2>Person Name</Column2>
            <Column1>Address</Column1>
            <Column2>House: E5, Block-G, Road-02</Column2>
            <Details>
                <Column1>Entry date</Column1>
                <Column2>6/6/13 12:04 PM</Column2>
                <Column1>height</Column1>
                <Column2>153</Column2>
                <Column1>weight</Column1>
                <Column2>53.5</Column2>
                <Column1>temperature</Column1>
                <Column2>98.67</Column2>
                <Column1>pulse rate</Column1>
                <Column2>76</Column2>
                <Advices>
                    <Advice>
                        <Column1>Title</Column1>
                        <Column2>Workout</Column2>
                        <Column1>Location</Column1>
                        <Column2>In the Park</Column2>
                    </Advice>
                </Advices>
            </Details>
        </SubSource>
    </Source>
</content>

我使用了几种xslt方法。但是,所有这些都没有按照需要查看数据,或者更少或没有正确格式化表格!!!

以下是我最好的方法(我没有做多表设计,因为我想先获取所有数据)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html"/>
    <xsl:template match="/">
        <html>
            <body>
                <table>
                    <xsl:apply-templates select="content/Source"/>
                </table>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="content/Source">
        <xsl:variable name="column" select="content/Source"/>
        <tr>
            <td>
                <xsl:value-of select="Column1"/>
            </td>
            <td>
                <xsl:value-of select="Column2"/>
            </td>
        </tr>
        <xsl:apply-templates select="SubSource"/>
    </xsl:template>
    <xsl:template match="SubSource">
        <tr>
            <td>
                <xsl:value-of select="Column1"/>
            </td>
            <td>
                <xsl:value-of select="Column2"/>
            </td>
        </tr>
        <xsl:apply-templates select="Details"/>
    </xsl:template>
    <xsl:template match="Details">
        <tr>
            <td>
                <xsl:value-of select="Column1"/>
            </td>
            <td>
                <xsl:value-of select="Column2"/>
            </td>
        </tr>
        <xsl:apply-templates select="Advices"/>
    </xsl:template>
    <xsl:template match="Advices">
        <xsl:for-each select="Advice">
            <tr>
                <td>
                    <xsl:value-of select="Column1"/>
                </td>
                <td>
                    <xsl:value-of select="Column2"/>
                </td>
            </tr>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

输出是:

 <table>
         <tr>
            <td>Name</td>
            <td>Organization Name</td>
         </tr>
         <tr>
            <td>Name</td>
            <td>Person Name</td>
         </tr>
         <tr>
            <td>Entry date</td>
            <td>6/6/13 12:04 PM</td>
         </tr>
         <tr>
            <td>Title</td>
            <td>Workout</td>
         </tr>
         <tr>
            <td>Title</td>
            <td>Eating Habit</td>
         </tr>
         <tr>
            <td>Name</td>
            <td>Organization Name</td>
         </tr>
         <tr>
            <td>Name</td>
            <td>Person Name</td>
         </tr>
         <tr>
            <td>Entry date</td>
            <td>6/6/13 12:04 PM</td>
         </tr>
         <tr>
            <td>Title</td>
            <td>Workout</td>
         </tr>
      </table>

我的目标是让表格布局与XML结构相同。

欢迎提供更好的XML格式的建议!

谢谢

1 个答案:

答案 0 :(得分:0)

这个XSLT 1.0样式表可以满足你的需要:它从一个未知元素名称的结构中创建嵌套的HTML表。

我唯一的先决条件是有<Column1>个元素可能后跟关联的<Column2>

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

  <xsl:output method="html" indent="yes" />

  <!-- #1: anything that has <Column1> children becomes a table -->
  <xsl:template match="*[Column1]">
    <table class="{name()}">
      <xsl:apply-templates select="*" mode="nested" />
    </table>
  </xsl:template>

  <!-- #2: ...if it's nested, it is wrapped in a table row first -->
  <xsl:template match="*[Column1]" mode="nested">
    <tr>
      <td colspan="2">
        <!-- this actually executes #1 because it uses no mode! -->
        <xsl:apply-templates select="." />
      </td>
    </tr>
  </xsl:template>

  <!-- #3: <Column1> governs the creation of table rows -->
  <xsl:template match="*[Column1]/Column1" mode="nested">
    <tr>
      <td><xsl:value-of select="." /></td>
      <td><xsl:value-of select="following-sibling::*[1][self::Column2]" /></td>
    </tr>
  </xsl:template>

  <!-- #4: suppress any other data field (like <Column2>) -->
  <xsl:template match="*[Column1]/*[not(*)]" mode="nested" />

</xsl:stylesheet>

请注意模板模式的使用:如果有多个模板可以匹配某个元素,您可以使用mode来区分它们。

在这种情况下,您需要创建嵌套表。在根级别(默认情况下),您只需创建一个<table>元素。

Hovever,如果您已经在<table>内,则必须先创建<tr> / <td>,但之后流程是相同的。

通过使用模式,我可以确保在正确的上下文中执行正确的模板,而不必在创建实际<table>时重复自己。

作为副作用,通过使用模式,我们可以创建一整套模板,这些模板可以放入现有样式表中,而不会影响已建立的工作流程。


following-sibling::*[1][self::Column2]&#34;以下第一个兄弟姐妹,但前提是它实际上是<Column2>。&#34;


模板#4是必要的,因为相当不明确的<xsl:apply-templates select="*" mode="nested" />也适用于<Column2>。但是,这些实际上已经由#3处理,这意味着除非我们明确地禁止它们,否则它们会生成不需要的重复输出。