如何使用XSLT转换选择XML中的特定节点或元素?

时间:2010-07-19 20:16:51

标签: xml xslt

我的XML是

<row>
  <entry>1.</entry>
  <entry>foo</entry>
  <entry>morefoo</entry>
</row>
<row>
  <entry>2.</entry>
  <entry>2foo</entry>
  <entry>2morefoo</entry>
</row>

使用XSLT,我试图在html表中表示这些信息,我想要一个序列号。列。

如何选择仅第一个“条目”标签的值?

4 个答案:

答案 0 :(得分:2)

  

我的XML是

<row> 
<entry>1.</entry> 
<entry>foo</entry> 
<entry>morefoo</entry> 
</row> 
<row> 
<entry>2.</entry> 
<entry>2foo</entry> 
<entry>2morefoo</entry> 
</row>

这是格式不正确的XML文档。格式良好的XML文档必须只有一个顶级元素。我将使用以下(更正为格式良好的)XML文档:

<rows>
    <row>
        <entry>1.</entry>
        <entry>foo</entry>
        <entry>morefoo</entry>
    </row>
    <row>
        <entry>2.</entry>
        <entry>2foo</entry>
        <entry>2morefoo</entry>
    </row>
</rows>
  

我如何选择价值   只有第一个“入口”标签?

/*/row/entry[1]

以上选择每个entry元素的第一个row 元素 - 。

/*/row[1]/entry[1]

以上选择文档中第一个entry元素的第一个row 元素 - 。

/*/row[2]/entry[1]

以上选择文档中第二个entry元素的第一个row 元素 - 。

(//entry)[1]

以上选择整个文档中的第一个entry 元素

//entry[1]

请注意,这与前一个表达式不同:这会选择文档中的每个entry元素,这是其父级的第一个entry子元素。

答案 1 :(得分:1)

//row/entry[1]

这将选择作为父节点的第一个子节点的所有entry标记。

答案 2 :(得分:1)

下面的XSLT将生成此表:

Serial No  Name   Description
1.         foo    morefoo 
2.         2foo   2morefoo 

示例文档:

<?xml version="1.0" encoding="utf-8"?>
<document>
  <row>
    <entry>1.</entry>
    <entry>foo</entry>
    <entry>morefoo</entry>
  </row>
  <row>
    <entry>2.</entry>
    <entry>2foo</entry>
    <entry>2morefoo</entry>
  </row>
</document>

<强> 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" indent="yes"/>

  <xsl:template match="/">
    <html>
      <head>
        <title>Sample</title>
      </head>
      <body>
        <table border="1">
          <tr>
            <th>Serial No</th>
            <th>Name</th>
            <th>Description</th>
          </tr>
          <xsl:apply-templates />
        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="row">
    <tr>
      <xsl:for-each select="entry">
        <td>
          <xsl:value-of select="."/>
        </td>
      </xsl:for-each>
    </tr>
  </xsl:template>

</xsl:stylesheet>

答案 3 :(得分:1)

在你的XSLT中你应该有这样的东西:

<!-- matches the root (not specified in your post) -->
<xsl:template match="/">
   <!-- at root level, make your table -->
   <table>
     <thead>.... </thead>
     <tbody>
       <!-- push the rows through, make sure the path is correct -->
       <xsl:apply-templates select="path/to/row" />
     </tbody>
   </table>
</xsl:template>

<xsl:template match="row">
   <!-- create the rows -->
   <tr>
     <!-- process first entry only, as you requested (why?) -->
     <xsl:apply-templates select="entry[1]" mode="first"/>
     <!-- process other entries -->
     <xsl:apply-templates select="entry[position() > 1]" mode="other"/>
   </tr>
</xsl:template>

<xsl:template match="entry" mode="first">
   <!-- maybe you want the first cell to be treated specially, i.e. as row header -->
   <th><xsl:value-of select="."/></th>
</xsl:template>

<xsl:template match="entry" mode="other">
   <!-- the other cells -->
   <td><xsl:value-of select="."/></td>
</xsl:template>

注意:上面的代码未经过测试,请将其用作您自己的实际代码和数据的模板。

输出类似于以下内容:

<table>
  <thead>....</thead>
  <tbody>
    <tr>
      <th>1.</th>
      <td>foo</td>
      <td>morefoo</td>
    </tr>
    <tr>
      <th>2.</th>
      <td>2foo</td>
      <td>2morefoo</td>
    </tr>
    <tr>....
  </tbody>
</table>