【问题标题】:Simple xsl:key doesn't match简单的 xsl:key 不匹配
【发布时间】:2021-09-15 07:46:13
【问题描述】:

无法确定此 xsl:key 示例工作的正确参数。我想要的是输出相同的 xhtml,并根据 root.xml 中的数据更改速率/名称字段。

XHMTL(主输入)

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>PZBank</title>
  </head>
  <body>
    <table style="width:100%">
       <tr>
          <th align="left">Product #1</th>
          <th align="left">Product #2</th>
          <th align="left">Product #3</th>
       </tr>
       <tr>
          <td name="name0">Whiz-bang</td>
          <td name="name1">Ulitmate</td>
          <td name="name2">Killer</td>
       </tr>
       <tr>
          <td name="rate0">2.09</td>
          <td name="rate1">1.99</td>
          <td name="rate2">3.19</td>
       </tr>
    </table>
  </body>
</html>

XML - root.xml

<root>
  <dbu>
    <product ord="0">
      <name>Amazing</name>
      <rate>4.5</rate>
    </product>
  </dbu>
  <dbu>
    <product ord="1">
      <name>Incredible</name>
      <rate>6.6</rate>
    </product>
  </dbu>
</root>

XSL

<xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all"
  expand-text="yes">
  <xsl:output method="html" omit-xml-declaration="yes" encoding="UTF-8" include-content-type="no"/>
  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:variable name="rooter" select="document('root.xml')"/>

  <xsl:key name="krate" match="product/rate" use="/root/dbu/product[@ord]"/>

  <xsl:key name="kname" match="name" use="@ord"/>

  <xsl:template match="td[starts-with(@name,'rate')]/text()">
    <xsl:variable name="ordv" select="substring-after(../@name,'rate')"/>
    <xsl:for-each select="$rooter">
      <xsl:value-of select="key('krate',$ordv)"/>
    </xsl:for-each>
  </xsl:template>

  <xsl:template match="td[starts-with(@name,'name')]/text()">
    {key('kname', substring-after(../@name, 'name'), $rooter)}
  </xsl:template>

</xsl:stylesheet>

发生的情况是输出中的名称/费率字段为空白,因此显然 xsl:key 调用不正确。我什至尝试了 2 种方法:krate 和 kname,但没有运气。我还在 xsl:key 上尝试了许多不同的 @ord xpath 字符串。

root.xml 只是一个测试版本。在生产中,它会更加复杂。

【问题讨论】:

    标签: xslt xpath xhtml saxon-js


    【解决方案1】:

    您可以对这两种方法都使用第二种方法。所以试试这个:

    <xsl:stylesheet version="3.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      exclude-result-prefixes="#all"
      expand-text="yes">
      <xsl:output method="html" omit-xml-declaration="yes" encoding="UTF-8" include-content-type="no"/>
      <xsl:mode on-no-match="shallow-copy"/>
      <xsl:strip-space elements="*" />
      
      <xsl:variable name="rooter" select="document('root.xml')"/>
      <xsl:key name="kord" match="/root/dbu/product" use="@ord"/>
      
      <xsl:template match="td[starts-with(@name,'rate')]/text()">{key('kord', substring-after(../@name, 'rate'), $rooter)/rate}</xsl:template>
    
      <xsl:template match="td[starts-with(@name,'name')]/text()">{key('kord', substring-after(../@name, 'name'), $rooter)/name}</xsl:template>
    
    </xsl:stylesheet>
    

    xsl:strip-space 删除元素之间的空行。
    如果你真的需要 xsl:for-each 来代替 rate,它可能看起来像这样:

    <xsl:template match="td[starts-with(@name,'rate')]/text()">
      <xsl:variable name="ordv" select="substring-after(../@name,'rate')"/>
      <xsl:for-each select="$rooter">
        <xsl:value-of select="key('kord',$ordv)/rate"/>
      </xsl:for-each>
    </xsl:template>
    

    它的输出是

    <!DOCTYPE HTML><html lang="en">
        <head>
            <title>PZBank</title>
        </head>
        <body>
            <table style="width:100%">
                <tr>
                    <th align="left">Product #1</th>
                    <th align="left">Product #2</th>
                    <th align="left">Product #3</th>
                </tr>
                <tr>
                    <td name="name0">Amazing</td>
                    <td name="name1">Incredible</td>
                    <td name="name2"></td>
                </tr>
                <tr>
                    <td name="rate0">4.5</td>
                    <td name="rate1">6.6</td>
                    <td name="rate2"></td>
                </tr>
            </table>
        </body>
    </html>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-16
      • 2019-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多