【问题标题】:xslt: How can I create a dynamic table?xslt:如何创建动态表?
【发布时间】:2009-04-17 15:02:48
【问题描述】:

给定这个 xml

<Documents>
<Section>
<SectionName>Green</SectionName>
  <Document>
    <FileName>Tier 1 Schedules</FileName>     
  </Document>
  <Document>
    <FileName>Tier 3 Schedules</FileName>      
  </Document>
  <Document>
    <FileName>Setback Schedule</FileName>    
  </Document>
  <Document>
    <FileName>Tier 2 Governance</FileName>    
  </Document>
</Section>
<Section>
<SectionName>MRO/Refurb</SectionName>
  <Document>
    <FileName>Tier 2 Governance</FileName>    
  </Document>
</Section>
</Documents>

xslt 是什么来输出这个 html

<table>
  <tr>
    <td>Green</td>
  </tr>
  <tr>
    <td>Tier 1 Schedules</td>
  </tr>
  <tr>
    <td>Tier 3 Schedules</td>
  </tr>
  <tr>
    <td>Setback Schedule</td>
  </tr>
  <tr>
    <td>Tier 2 Governance</td>
  </tr>
  <tr>
    <td>MRO/Refurb</td>
  </tr>
  <tr>
    <td>Tier 2 Governance</td>
  </tr>
</table>

我可以在 asp.net 中执行此操作,但不确定如何在 xslt 中执行循环。

谢谢, 铝

【问题讨论】:

  • 如 marc_s 的回答所示,您不会在 XSLT 中循环。它是一种声明性语言。忘记程序性思维。
  • @bortzmeyer:严格来说,您当然会在 XSLT 中循环。 :-) 只是表达方式不同而已。
  • 如果我想做多列怎么办?
  • 嗯...应该是什么样子?
  • 使用上面问题中的xml,每个部分都在自己的列中,然后每个文档在该列中的一行中。

标签: asp.net xml xslt


【解决方案1】:
<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />

  <xsl:template match="/">
    <table>
      <xsl:apply-templates select="//SectionName | //FileName" />
    </table>
  </xsl:template>

  <xsl:template match="SectionName | FileName">
    <tr>
      <td><xsl:value-of select="." /></td>
    </tr>
  </xsl:template>

</xsl:stylesheet>

【讨论】:

  • +1 - 该死 - 你的答案是准确的,甚至更简洁(再次!):-)
【解决方案2】:

其实有一个比Tomalak提出的方案稍微简单一点的解决方案

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:strip-space elements="*"/>

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

    <xsl:template match="SectionName | FileName">
        <tr>
            <td>
                <xsl:value-of select="." />
            </td>
        </tr>
    </xsl:template>
</xsl:stylesheet>

当对最初提供的 XML 文档应用这种转换时,就会产生想要的结果

<table>
   <tr>
      <td>Green</td>
   </tr>
   <tr>
      <td>Tier 1 Schedules</td>
   </tr>
   <tr>
      <td>Tier 3 Schedules</td>
   </tr>
   <tr>
      <td>Setback Schedule</td>
   </tr>
   <tr>
      <td>Tier 2 Governance</td>
   </tr>
   <tr>
      <td>MRO/Refurb</td>
   </tr>
   <tr>
      <td>Tier 2 Governance</td>
   </tr>
</table>

请注意

  1. &lt;xsl:apply-templates&gt; 指令未明确指定必须处理的节点列表。在这里,我们依赖于这样一个事实,即文档中唯一的非空白节点是我们有匹配模板的节点的子节点。

  2. 对于这个特定的 XML 文档,我们甚至可以将 &lt;xsl:template match="SectionName | FileName"&gt; 的匹配模式更改为:&lt;xsl:template match="text()"&gt;,并且转换仍然会产生想要的结果。

  3. &lt;xsl:strip-space&gt; 指令的使用

【讨论】:

  • 我认为明确选择想要应用模板的节点会带来更好的性能。在您的解决方案中,所有节点都会被访问,而不仅仅是感兴趣的节点。这是真的还是没有区别?我不确定,也许我的“//SectionName | //FileName”是更大的性能杀手。
  • @Tomalak 如果 XSLT 处理器没有很好地优化,选择由“//SectionName | //FileName”指定的节点可能会导致对整个 XML 文档进行两次完整扫描。如果可能,最好避免使用“//”缩写。
  • 我明白了。让我们假设源文档包含比我们想要的输出更多的节点。您将如何忽略它们?像这样:?
  • @Tomalak 我宁愿使用: 如果有很多元素可以有我们感兴趣的文本,在 XSLT 1.0 中,我必须在模板正文中使用 。在 XSLT 2.0 中,可以在匹配模式中使用变量引用。
【解决方案3】:

这样的事情应该可以解决问题:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="html" indent="yes"/>

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

  <xsl:template match="SectionName">
    <tr>
      <td>
        <xsl:value-of select="."/>
      </td>
    </tr>
  </xsl:template>

  <xsl:template match="Document">
    <tr>
      <td>
        <xsl:value-of select="FileName"/>
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

马克

【讨论】:

  • 一个吹毛求疵的评论:你能说一下你包含 元素的目的是什么吗? :) 也许你对它的效果的期望是错误的。
  • 哦,抱歉 - 这是 Visual Studio 默认模板的残余......不应该在那里。
猜你喜欢
  • 2022-08-18
  • 1970-01-01
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
相关资源
最近更新 更多