使用XSLT将第一个HTML表行转换为每个表的标题行

时间:2011-02-08 03:34:55

标签: html xml xslt

我的XML中有一些html内容。以前我可以使用<xsl:copy-of select="customFields/customField[@name='mainContent']/html"/>将内容拉到正确的区域。新要求是将每个表格<tr>中的第一个<tbody>转换为一组thead/tr/th

我对如何转换感到困惑,事实上甚至不知道在哪里开始:

...

<customField name="mainContent" type="Html">
    <html>
        <h1>Page Heading</h1>
        <p>Gusto te minim tempor elit quam. Dolore vel accumsan parum option me. Demonstraverunt congue nisl soluta tincidunt seacula. Soluta saepius demonstraverunt praesent claritatem mutationem. Modo te ullamcorper vel augue veniam. Nunc investigationes dolor iriure typi in.</p>
        <p>Gusto te minim tempor elit quam. Dolore vel accumsan parum option me. Demonstraverunt congue nisl soluta tincidunt seacula. Soluta saepius demonstraverunt praesent claritatem mutationem. Modo te ullamcorper vel augue veniam. Nunc investigationes dolor iriure typi in.</p>
        <table cellspacing="0" cellpadding="0" summary="" border="0">
            <tbody>
                <tr>
                    <td>Heading 1</td>
                    <td>Heading 2</td>
                    <td>Heading 3</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
            </tbody>
        </table>
    </html>
</customField>
...

成:

...
<customField name="mainContent" type="Html">
    <html>
        <h1>Page Heading</h1>
        <p>Gusto te minim tempor elit quam. Dolore vel accumsan parum option me. Demonstraverunt congue nisl soluta tincidunt seacula. Soluta saepius demonstraverunt praesent claritatem mutationem. Modo te ullamcorper vel augue veniam. Nunc investigationes dolor iriure typi in.</p>
        <p>Gusto te minim tempor elit quam. Dolore vel accumsan parum option me. Demonstraverunt congue nisl soluta tincidunt seacula. Soluta saepius demonstraverunt praesent claritatem mutationem. Modo te ullamcorper vel augue veniam. Nunc investigationes dolor iriure typi in.</p>
        <table cellspacing="0" cellpadding="0" summary="" border="0">
            <thead>
                <tr>
                    <th>Heading 1</th>
                    <th>Heading 2</th>
                    <th>Heading 3</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
            </tbody>
        </table>
    </html>
</customField>
...

3 个答案:

答案 0 :(得分:1)

  

我的内容中有一些HTML内容   XML。以前我可以使用   <xsl:copy-of select="customFields/customField[@name='mainContent']/html"/>   将内容拉入正确的内容   区域。新要求是转换   每个表中的第一个<tr>   <tbody>thead/tr/th

此转化

<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="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="tbody/tr[1]">
  <thead>
    <tr>
      <xsl:apply-templates/>
    </tr>
  </thead>
 </xsl:template>

 <xsl:template match="tbody/tr[1]/td">
  <th><xsl:apply-templates/></th>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<customField name="mainContent" type="Html">
    <html>
        <h1>Page Heading</h1>
        <p>Gusto te minim tempor elit quam. Dolore vel accumsan parum option me. Demonstraverunt congue nisl soluta tincidunt seacula. Soluta saepius demonstraverunt praesent claritatem mutationem. Modo te ullamcorper vel augue veniam. Nunc investigationes dolor iriure typi in.</p>
        <p>Gusto te minim tempor elit quam. Dolore vel accumsan parum option me. Demonstraverunt congue nisl soluta tincidunt seacula. Soluta saepius demonstraverunt praesent claritatem mutationem. Modo te ullamcorper vel augue veniam. Nunc investigationes dolor iriure typi in.</p>
        <table cellspacing="0" cellpadding="0" summary="" border="0">
            <tbody>
                <tr>
                    <td>Heading 1</td>
                    <td>Heading 2</td>
                    <td>Heading 3</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
            </tbody>
        </table>
    </html>
</customField>

产生完全正确的结果

<customField name="mainContent" type="Html">
   <html>
      <h1>Page Heading</h1>
      <p>Gusto te minim tempor elit quam. Dolore vel accumsan parum option me. Demonstraverunt congue nisl soluta tincidunt seacula. Soluta saepius demonstraverunt praesent claritatem mutationem. Modo te ullamcorper vel augue veniam. Nunc investigationes dolor iriure typi in.</p>
      <p>Gusto te minim tempor elit quam. Dolore vel accumsan parum option me. Demonstraverunt congue nisl soluta tincidunt seacula. Soluta saepius demonstraverunt praesent claritatem mutationem. Modo te ullamcorper vel augue veniam. Nunc investigationes dolor iriure typi in.</p>
      <table cellspacing="0" cellpadding="0" summary="" border="0">
         <tbody>
            <thead>
               <tr>
                  <th>Heading 1</th>
                  <th>Heading 2</th>
                  <th>Heading 3</th>
               </tr>
            </thead>
            <tr>
               <td>sample</td>
               <td>sample</td>
               <td>sample</td>
            </tr>
            <tr>
               <td>sample</td>
               <td>sample</td>
               <td>sample</td>
            </tr>
            <tr>
               <td>sample</td>
               <td>sample</td>
               <td>sample</td>
            </tr>
            <tr>
               <td>sample</td>
               <td>sample</td>
               <td>sample</td>
            </tr>
         </tbody>
      </table>
   </html>
</customField>

请注意:

使用“覆盖标识规则”设计模式。这是最基本和最强大的XSLT设计模式。

<强>更新

正如Flynn1179所注意到的那样,OP对问题的定义(上图)与他提供的想要结果的输出不一致。在此输出中,tr内部的第一个tbody不仅转换为thead/tr(及其td子项转换为th),而{{1}移动到thead之外。

如果这确实是OP想要的,这里也是修改后的解决方案:

tbody

应用于同一XML文档时,结果为

<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="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="tbody/tr[1]">
  <thead>
   <tr>
    <xsl:apply-templates/>
   </tr>
  </thead>
  <tbody>
   <xsl:apply-templates 
        select="following-sibling::tr"/>
  </tbody>
 </xsl:template>

 <xsl:template match="tbody/tr[1]/td">
  <th>
   <xsl:apply-templates/>
  </th>
 </xsl:template>

 <xsl:template match="tbody">
  <xsl:apply-templates select="tr[1]"/>
 </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

试试这个:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="tbody">
   <xsl:element name="thead">
     <xsl:apply-templates select="tr[1]" />
   </xsl:element>
   <xsl:element name="tbody">
     <xsl:apply-templates select="tr[position()!=1]" />
   </xsl:element>
 </xsl:template>

 <xsl:template match="tr[1]/td">
   <xsl:element name="th">
     <xsl:apply-templates />
   </xsl:element>
 </xsl:template>

</xsl:stylesheet>

它只是替换现有的tbody元素,其中thead包含第一行,tbody包含除第一行以外的所有元素,然后替换所有td元素第一个tr代替th

答案 2 :(得分:0)

只是为了好玩,这个样式表:

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="tbody">
        <xsl:apply-templates mode="header"/>
        <xsl:call-template name="identity"/>
    </xsl:template>
    <xsl:template match="tr[1]"/>
    <xsl:template match="tr" mode="header"/>
    <xsl:template match="tr[1]" mode="header">
        <thead>
            <xsl:call-template name="identity"/>
        </thead>
    </xsl:template>
    <xsl:template match="tr[1]/td">
        <th>
            <xsl:apply-templates select="node()|@*"/>
        </th>
    </xsl:template>
</xsl:stylesheet>

输出:

<customField name="mainContent" type="Html">
    <html>
        <h1>Page Heading</h1>
        <p>Gusto te minim tempor elit quam. Dolore vel accumsan parum option me. Demonstraverunt congue nisl soluta tincidunt seacula. Soluta saepius demonstraverunt praesent claritatem mutationem. Modo te ullamcorper vel augue veniam. Nunc investigationes dolor iriure typi in.</p>
        <p>Gusto te minim tempor elit quam. Dolore vel accumsan parum option me. Demonstraverunt congue nisl soluta tincidunt seacula. Soluta saepius demonstraverunt praesent claritatem mutationem. Modo te ullamcorper vel augue veniam. Nunc investigationes dolor iriure typi in.</p>
        <table cellspacing="0" cellpadding="0" summary="" border="0">
            <thead>
                <tr>
                    <th>Heading 1</th>
                    <th>Heading 2</th>
                    <th>Heading 3</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
                <tr>
                    <td>sample</td>
                    <td>sample</td>
                    <td>sample</td>
                </tr>
            </tbody>
        </table>
    </html>
</customField>