选择xslt中的多个元素

本文关键字:元素 xslt 选择 | 更新日期: 2023-09-27 18:04:02

我是XSLT的新手。我有一个问题。问题:我有一个类似于:

的xml
<data>
  <element>
     <Title>Title1</Title>
     <Author>Author1</Author>
  </element>
  <element>
     <Title>Title2</Title>
     <Author>Author2</Author>
  </element>
  <element>
     <Title>Title3</Title>
     <Author>Author3</Author>
  </element>
  <element>
     <Title>Title4</Title>
     <Author>Author4</Author>
  </element>
  (...)
</data>

我想要一个类似的结构:

<table>
      <tr>
        <td style="padding:2px 0px 5px 0px;">
           Title1 Author1
           Title2 Author2
        </td>
      </tr>
      <tr>
        <td style="padding:2px 0px 5px 0px;">
           Title3 Author3
           Title4 Author4
        </td>
      </tr>
     (...)
</table>

请注意,作者1、2被分组在一起,同样地,作者3、4也被分组在一起。它们是根据位置分组的(当然,我将有一个名称而不是Author1,因此我无法从xml中提取数字)。位置1和位置2位置3和位置4…

我在xslt中尝试了这样的操作:

<xsl:for-each select="element">
      <xsl:if test="(position() mod 2 = 0)">
        <tr>    <------ THIS APPEARS AS NOT CLOSED
          <td style="padding:2px 0px 5px 0px;">    <------ THIS APPEARS AS NOT CLOSED
            <xsl:call-template name="content"/>
      </xsl:if>
      <xsl:if test="(position() mod 2 = 1)">
        <xsl:call-template name="content"/>
        </td> <------ THIS WOULD BE THE CLOSED TD
        </tr> <------ THIS WOULD BE THE CLOSED TR
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

<xsl:call-template name="content"/>只是为我获取所需的信息,没有什么花哨的,只是xsl:value-of select

问题:

  1. 如何生成打开和关闭的<td><tr> ?上面的xslt确实可以编译,因为看起来tdtr可能保持未关闭状态,这似乎是非法的。
  2. 我听说xslt中的for-each是一个不好的模式。这是真的吗?如果是的话,你会推荐什么?

我在c#中使用XslCompiledTransform,所以xslt 2应该工作。

选择xslt中的多个元素

尝试:

XSLT 1.0

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/data">
    <table>
        <xsl:for-each select="element[position() mod 2 = 1]">
            <tr>
                <td>
                    <xsl:value-of select="Title"/>
                    <xsl:text> </xsl:text>
                    <xsl:value-of select="Author"/>
                    <br/>
                    <xsl:value-of select="following-sibling::element[1]/Title"/>
                    <xsl:text> </xsl:text>
                    <xsl:value-of select="following-sibling::element[1]/Author"/>
                </td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>
</xsl:stylesheet>

这个XSLT应该可以帮助您入门。我添加了空格,但如果它们不相关,您可以简单地删除<xsl:text>元素:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    <xsl:template match="data">
        <table>
            <xsl:apply-templates select="element[(position()+1) mod 2 = 0]"/>
        </table>
    </xsl:template>
    <xsl:template match="element">
        <tr>
            <td style="padding:2px 0px 5px 0px;">
                <xsl:text>&#xa;         </xsl:text>
                <xsl:apply-templates select="*"/>
                <xsl:text>&#xa;         </xsl:text>
                <xsl:apply-templates select="following-sibling::element[1]/*"/>
                <xsl:text>&#xa;      </xsl:text>
            </td>
        </tr>
    </xsl:template>
    <xsl:template match="Title">
        <xsl:value-of select="."/>
        <xsl:text> </xsl:text>
    </xsl:template>
    <xsl:template match="Author">
        <xsl:value-of select="."/>
    </xsl:template>
</xsl:stylesheet>

您不需要任何for-each块或复杂的嵌套,因为每个模板都是针对每个节点递归地处理的,所以同一个模板会被处理多次。