XSLT允许不匹配的标签?

Sil*_*viu 3 html xml xslt

<xsl:template match="location">
        <xsl:if test="not(preceding::location)">
            <table>
                <tr>
                    <th>Name</th>
                    <th>City</th>
                    <th>State</th>
                    <th>Zip Code</th>
                    <th>Country</th>
                </tr>
        </xsl:if>
        <tr>
            <td><xsl:value-of select=".//name"/></td>
            <td><xsl:value-of select=".//city"/></td>
            <td><xsl:value-of select=".//state"/></td>
            <td><xsl:value-of select=".//zip"/></td>
            <td><xsl:value-of select=".//countdy"/></td>
        </tr>
        <xsl:if test="not(following::location)">
            </table>
        </xsl:if>
    </xsl:template>
Run Code Online (Sandbox Code Playgroud)

是否允许在XSLT中使用不匹配的标签...或者是否有其他方法可以实现相同的预期效果?

Dan*_*ley 5

就像Dimitre所说,没有办法在XSLT中允许不匹配的标签.不过应该没有理由让标签不匹配.

查看您的模板,看起来您正在尝试从<location>XML实例的所有元素构建一个html表.你试图在第一次打开表<location>并尝试在最后关闭表<location>.

最简单的方法是在更高级别(父级/祖级)打开表,然后使用<location>数据填充表.

这是一个有3 <location>s 的示例XML文件:

<doc>
  <location>
    <name>name 1</name>
    <city>city 1</city>
    <state>state 1</state>
    <zip>zip 1</zip>
    <country>country 1</country>
  </location>
  <location>
    <name>name 2</name>
    <city>city 2</city>
    <state>state 2</state>
    <zip>zip 2</zip>
    <country>country 2</country>
  </location>
  <location>
    <name>name 3</name>
    <city>city 3</city>
    <state>state 3</state>
    <zip>zip 3</zip>
    <country>country 3</country>
  </location>
</doc>
Run Code Online (Sandbox Code Playgroud)

这是一个将创建表的样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="doc">
    <!--The table is inserted here.-->
    <table>
      <tr>
        <th>Name</th>
        <th>City</th>
        <th>State</th>
        <th>Zip Code</th>
        <th>Country</th>
      </tr>
      <!--This is where we apply the templates to populate the rows.-->
      <xsl:apply-templates select="location"/>
    </table>
  </xsl:template>

  <!--This template populates the row(s).-->
  <xsl:template match="location">
    <tr>
      <td>
        <xsl:value-of select="name"/>
      </td>
      <td>
        <xsl:value-of select="city"/>
      </td>
      <td>
        <xsl:value-of select="state"/>
      </td>
      <td>
        <xsl:value-of select="zip"/>
      </td>
      <td>
        <xsl:value-of select="country"/>
      </td>
    </tr>
  </xsl:template>

</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

这是输出:

<table>
   <tr>
      <th>Name</th>
      <th>City</th>
      <th>State</th>
      <th>Zip Code</th>
      <th>Country</th>
   </tr>
   <tr>
      <td>name 1</td>
      <td>city 1</td>
      <td>state 1</td>
      <td>zip 1</td>
      <td>country 1</td>
   </tr>
   <tr>
      <td>name 2</td>
      <td>city 2</td>
      <td>state 2</td>
      <td>zip 2</td>
      <td>country 2</td>
   </tr>
   <tr>
      <td>name 3</td>
      <td>city 3</td>
      <td>state 3</td>
      <td>zip 3</td>
      <td>country 3</td>
   </tr>
</table>
Run Code Online (Sandbox Code Playgroud)

如果由于某种原因你需要创建<table>第一个<location>,你仍然可以这样做.但它需要更多代码.

以下样式表生成与第一个样式表相同的输出:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/doc">
    <xsl:apply-templates/>
  </xsl:template>

  <!--The table is created at the first location and
    the first row is populated.-->
  <xsl:template match="location[1]">
    <table>
      <tr>
        <th>Name</th>
        <th>City</th>
        <th>State</th>
        <th>Zip Code</th>
        <th>Country</th>
      </tr>
      <xsl:call-template name="location-row"/>
      <!--Here is where we apply the other template to populate the other rows.
        Notice we use a "mode" to differentiate the template from the generic
        "location" template.-->
      <xsl:apply-templates select="following-sibling::location" mode="not-first"/>
    </table>
  </xsl:template>

  <!--This template will output the other rows.-->
  <xsl:template match="location" mode="not-first" name="location-row">
    <tr>
      <td>
        <xsl:value-of select="name"/>
      </td>
      <td>
        <xsl:value-of select="city"/>
      </td>
      <td>
        <xsl:value-of select="state"/>
      </td>
      <td>
        <xsl:value-of select="zip"/>
      </td>
      <td>
        <xsl:value-of select="country"/>
      </td>
    </tr>
  </xsl:template>

  <!--This generic template matches locations other than the first one. 
    Basically it is consuming it so we don't get duplicate output.--> 
  <xsl:template match="location"/>

</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)