简体   繁体   English

将具有键值对的 XML 转换为 HTML 表

[英]Transform XML with key and value pairs to HTML table

Trying to transform XML to HTML tables.尝试将 XML 转换为 HTML 表。 I can find plenty of examples on creating an XSLT style sheet for XML where the format is like this:我可以找到很多关于为 XML 创建 XSLT 样式表的示例,格式如下:

<catalog>
  <cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
  </cd>
</catalog>

But what if the format is like this, as it is in my dataset?但是如果格式是这样的,就像我的数据集中的那样呢?

<DataObjects>
  <ObjectSelect>
    <mdNm>my-catalog</mdNm>
    <meNm>Catalog Selection A1</meNm>
  </ObjectSelect>
  <DataInstances>
    <DataInstance>
      <instanceId>Cd</instanceId>
        <field name='title'>Empire Burlesque</field>
        <field name='artist'>Bob Dylan</field>
        <field name='country'>USA</field>
        <field name='company'>Columbia</field>
    </DataInstance>
    <DataInstance>
      <instanceId>Movie</instanceId>
        <field name='title'>Casablanca</field>
        <field name='director'>Michael Curtiz</field>
        <field name='genre'>Drama</field>
    </DataInstance>
  </DataInstances>
</DataObjects>

Each InstanceId has a single entry, with unique field names, and I'm trying to get create a table output for each unique InstanceId, so a "Cd" table, a "Movie" table, and so on.每个 InstanceId 都有一个条目,具有唯一的字段名称,我试图为每个唯一的 InstanceId 创建一个表 output,所以一个“Cd”表,一个“电影”表,等等。 Each field would be a new row, the first column would be what is in name=, and the value would be in the second column of the row.每个字段将是一个新行,第一列将是 name= 中的内容,值将在该行的第二列中。 I think once I figure out how to grab the value from name="" and put it as a row name, I'll be able to figure out the rest. All the tutorials talk about using value-of, but that only works if the format is like the first example given.我想一旦我弄清楚如何从 name="" 中获取值并将其作为行名,我就能弄清楚 rest。所有教程都讨论使用 value-of,但这只有在以下情况下才有效格式就像给出的第一个例子。

An example XSLT that I'm using as a starting point.我使用的示例 XSLT 作为起点。 It does not like the field name= format.它不喜欢 field name= 格式。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <h2>Catalog Selection A1</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Name</th>
        <th>Value</th>
      </tr>
      <xsl:for-each select="DataObjects/DataInstances/DataInstance/instanceId/Cd">
      <tr>
        <td>Title</td>
        <td><xsl:value-of select="title" /></td>
      </tr>
      <tr>
        <td>Artist</td>
        <td><xsl:value-of select="artist" /></td>
      </tr>
      <tr>
        <td>Country</td>
        <td><xsl:value-of select="country" /></td>
      </tr>
      <tr>
        <td>Company</td>
        <td><xsl:value-of select="company" /></td>
      </tr>
      </xsl:for-each>
      <xsl:for-each select="DataObjects/DataInstances/DataInstance/instanceId/Movie">
      <tr>
        <td>Title</td>
        <td><xsl:value-of select="title" /></td>
      </tr>
      <tr>
        <td>Director</td>
        <td><xsl:value-of select="director" /></td>
      </tr>
      <tr>
        <td>Genre</td>
        <td><xsl:value-of select="genre" /></td>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

The output I'm trying to generate is a basic html table like this,我要生成的 output 是一个基本的 html 表,如下所示,

<html>
  <body>
    <h2>Catalog Selection A1</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Name</th>
        <th>Value</th>
      </tr>
      <tr>
        <td>Title</td>
        <td>Empire Burlesque</td>
      </tr>
      <tr>
        <td>Artist</td>
        <td>Bob Dylan</td>
      </tr>
      <tr>
        <td>Country</td>
        <td>USA</td>
      </tr>
      <tr>
        <td>Company</td>
        <td>Columbia</td>
      </tr>
    </table>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Name</th>
        <th>Value</th>
      </tr>
      <tr>
        <td>Title</td>
        <td>Casablanca</td>
      </tr>
      <tr>
        <td>Director</td>
        <td>Michael Curtiz</td>
      </tr>
      <tr>
        <td>Genre</td>
        <td>Drama</td>
      </tr>
    </table>
  </body>
</html>

I would suggest you do something along the lines of:我建议你按照以下方式做一些事情:

XSLT 1.0 XSLT 1.0

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

<xsl:template match="/DataObjects">
    <html>
        <body>
            <h2>
                <xsl:value-of select="ObjectSelect/meNm" />
            </h2>
            <h3>Cds</h3>
            <xsl:for-each select="DataInstances/DataInstance[instanceId='Cd']">
                <xsl:call-template name="table"/>
            </xsl:for-each>
            <h3>Movies</h3>
            <xsl:for-each select="DataInstances/DataInstance[instanceId='Movie']">
                <xsl:call-template name="table"/>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>

<xsl:template name="table">
    <table border="1">
        <tr>
            <th>Name</th>
            <th>Value</th>
        </tr>
        <xsl:for-each select="field">
            <tr>
                <td>
                    <xsl:value-of select="@name" />
                </td>
                <td>
                    <xsl:value-of select="." />
                </td>
            </tr>
        </xsl:for-each> 
    </table>
</xsl:template>

</xsl:stylesheet>

This minimizes code duplication by (1) using a named template to produce a table for any kind of instanceId and (2) processing each field to a row with name and value.这通过 (1) 使用命名模板为任何类型的instanceId生成表和 (2) 将每个field处理为具有名称和值的行来最大限度地减少代码重复。 However this also means that it will produce a row for every field in the input.然而,这也意味着它将为输入中的每个field生成一行。 If that's not what you want, then more work is required.如果这不是您想要的,则需要做更多的工作。


Added:添加:

If you only have one of each kind, and you don't mind preserving the original order, then you can do simply:如果您只有一种,并且您不介意保留原始订单,那么您可以简单地执行以下操作:

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

<xsl:template match="/DataObjects">
    <html>
        <body>
            <h2>
                <xsl:value-of select="ObjectSelect/meNm" />
            </h2>
            <xsl:for-each select="DataInstances/DataInstance">
                <table border="1">
                    <tr>
                        <th>Name</th>
                        <th>Value</th>
                    </tr>
                    <xsl:for-each select="field">
                        <tr>
                            <td>
                                <xsl:value-of select="@name" />
                            </td>
                            <td>
                                <xsl:value-of select="." />
                            </td>
                        </tr>
                    </xsl:for-each> 
                </table>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>

</xsl:stylesheet>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM