【问题标题】:XSLT Select by dynamic property valueXSLT 按动态属性值选择
【发布时间】:2015-02-23 17:18:53
【问题描述】:

我有以下表示二维数组的 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<Prop Name='Test' Type='Array' LBound='[0][0]' HBound='[9][9]' ElementType='String' Flags='0x0'>
    <Value ID='[0][0]'>1</Value>
    <Value ID='[1][0]'>2</Value>
    <Value ID='[2][0]'>3</Value>
    <Value ID='[0][1]'>10</Value>
    <Value ID='[1][1]'>11</Value>
    <Value ID='[2][1]'>12</Value>       
</Prop>

“ID”属性中的第一个括号值是数组中的行,第二个是列。 'Prop' 中的 'Value' 元素的实际数量可能会有所不同,但我将始终拥有一个 2D 数组。

我需要将其格式化为一个包含 2 列的 HTML 表格:

为此,我有以下 XSLT,它基本上通过并将所有以“[0]”结尾的元素打印到第一列,然后尝试找到以“[1]”结尾的匹配元素:

<?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>Name Value Pairs</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th style="text-align:left">Name</th>
        <th style="text-align:left">Value</th>  
      </tr>   
      <xsl:for-each select="Prop[@Name='Test']/Value">
        <xsl:if test="contains(self::Value/@ID,'][0]')">
          <tr>  
            <td><xsl:value-of select="self::Value"/></td>
            <td><xsl:value-of select="parent::Prop/Value[@ID=concat('[',position()-1,'][1]')]"/></td>                       
          </tr>  
        </xsl:if>
      </xsl:for-each>    
    </table>
  </body>
  </html>
</xsl:template>    
</xsl:stylesheet>

然而,这会将第二列返回为空,问题似乎是当我尝试使用 @ID 属性中的 concat 函数来动态更改其值时。

我在这里做错了什么?

【问题讨论】:

    标签: arrays xml xslt properties


    【解决方案1】:

    鉴于您的输入 XML,此 XSLT:

    <?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>Name Value Pairs</h2>
            <table border="1">
              <tr bgcolor="#9acd32">
                <th style="text-align:left">Name</th>
                <th style="text-align:left">Value</th>  
              </tr>   
              <xsl:for-each select="Prop[@Name='Test']/Value">
                <xsl:if test="contains(@ID,'][0]')">
                  <xsl:variable name="pos" select="position()"/>
                  <tr>  
                    <td><xsl:value-of select="."/></td>
                    <td>
                      <xsl:value-of select="../Value[@ID=concat('[',$pos - 1,'][1]')]"/>
                    </td>                       
                  </tr>  
                </xsl:if>
              </xsl:for-each>    
            </table>
          </body>
        </html>
      </xsl:template>    
    </xsl:stylesheet>
    

    将生成此 HTML:

    <html>
       <body>
          <h2>Name Value Pairs</h2>
          <table border="1">
             <tr bgcolor="#9acd32">
                <th style="text-align:left">Name</th>
                <th style="text-align:left">Value</th>
             </tr>
             <tr>
                <td>1</td>
                <td>10</td>
             </tr>
             <tr>
                <td>2</td>
                <td>11</td>
             </tr>
             <tr>
                <td>3</td>
                <td>12</td>
             </tr>
          </table>
       </body>
    </html>
    

    呈现如下:

    【讨论】:

    • 这非常有效。所以基本上我只需要创建一个变量而不是直接在 ID 条件中使用 position(),对吗?
    • 对,这是关键的变化;其他变化是轻微的风格改进。
    猜你喜欢
    • 1970-01-01
    • 2017-06-09
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多