Преобразуйте первую строку таблицы HTML в строку заголовка для каждой таблицы, используя XSLT - PullRequest
5 голосов
/ 08 февраля 2011

У меня есть некоторый HTML-контент внутри моего XML. Ранее я мог просто использовать <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 ]

1 голос
/ 08 февраля 2011

У меня есть некоторое содержание 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.

UPDATE

Как заметил Flynn1179, определение проблемы ОП (см. Выше) не согласуется с выводом, который он предоставляет в качестве желаемого результата. В этих выходных данных не только первая tr внутри tbody преобразуется в thead/trtd дочерних элементов в th), но thead перемещается за пределы tbody.

В случае, если это действительно то, чего хочет ОП, здесь также есть измененное решение для этого случая:

<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>

при применении к тому же 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">
         <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>
0 голосов
/ 09 февраля 2011

Просто для удовольствия, эта таблица стилей:

<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>
0 голосов
/ 08 февраля 2011

Попробуйте:

<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 вместо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...