Обработка данных неупорядоченного списка XHTML (хорошо отформатированный XML) для группировки и сортировки XML - PullRequest
1 голос
/ 20 сентября 2011

Мне нужно преобразовать документ XHTML (хорошо отформатированный XML) в стандартный документ XML.

Ввод:

<?xml version="1.0" encoding="iso-8859-1"?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  <head>
    <title>HTML Document Title</title>
  </head>
  <body>
    <h1>Welcome</h1>
    <div class="container">
      <ul>
        <li>
          <a href="a.html" title="abcdef AAA">New York</a>
        </li>
        <li>
          <a href="b.html" title="abcdef AAA">Los Angles</a>
        </li>
        <li>
          <a href="c.html" title="abcdef AAA">Alaska</a>
        </li>
        <li>
          <a href="d.html" title="abcdef BBB">Florida</a>
        </li>
        <li>
          <a href="e.html" title="zyxwvu AAA"><em>California</em></a>
        </li>
      </ul>
    </div>
  </body>
</html>

Примечание: Я заметил, что объявление DOCTYPE и простые комментарии вызывают сбой при разборе XSLT.Итак, я вручную удаляю их перед анализом XSL.Чтобы правильно проанализировать вывод, в настоящее время используется префикс «xhtml:», как указано в сообщении: Можно ли проанализировать HTML с помощью XSLT? .

Группировать элементы на основе значения заголовка тегов (подстрока 2-я часть), например, AAA, BBB и т. д. Дальнейшая группировка по 1-й части значения атрибута title (например, abcdef / zyxwvu) или наличию тега .Всего будет четыре элемента, таких как , , и на выходе.Это желательно.

Ожидаемый результат:

<root>
    <element title="hard-coded title" href="hard-coded url">
        <element title="AAA" href="AAA.html">
            <abcdef>
                <element title="Alaska" href="c.html">
                <element title="Los Angles" href="b.html">
                <element title="New York" href="a.html">
            </abcdef>
            <zyxwvu>
                <element title="California" href="e.html">
            </zyxwvu>
        </element>
        <element title="BBB" href="BBB.html">
            <abcdef>
                <element title="Florida" href="d.html">
            </abcdef>
        </element>
    </element>
</root>

Буду признателен, если решение будет предоставлено в XSLT v1.0 и v2.0.

1 Ответ

0 голосов
/ 21 сентября 2011

Это преобразование :

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

 <xsl:key name="kaByTail" match="x:a"
  use="substring-after(@title, ' ')"/>

 <xsl:key name="kaByHeadAndTail" match="x:a"
  use="concat(substring-before(@title, ' '),
              '+',
              substring-after(@title, ' ')
              )"/>
 <xsl:variable name="vAncors" select="//x:a"/>

 <xsl:template match="/">
  <root>
    <element title="hard-coded title" href="hard-coded url">
     <xsl:for-each select=
      "$vAncors
         [generate-id()
         =
          generate-id(key('kaByTail',
                           substring-after(@title, ' ')
                          )
                           [1]
                      )
         ]">
         <xsl:variable name="vKey"
              select="substring-after(@title, ' ')"/>

         <xsl:variable name="vGroup" select=
         "key('kaByTail', $vKey)"/>

        <element title="{$vKey}" href="{$vKey}.html">

         <xsl:for-each select=
         "$vGroup
            [generate-id()
            =
             generate-id(key('kaByHeadAndTail',
                             concat(substring-before(@title, ' '),
                                   '+',
                                    $vKey
                                    )
                            )
                             [1]
                         )
             ]

         ">
          <xsl:variable name="vKey2"
               select="substring-before(@title, ' ')"/>

          <xsl:element name="{$vKey2}">
           <xsl:for-each select=
            "key('kaByHeadAndTail',
                 concat($vKey2,'+',$vKey)
                 )">
            <xsl:sort/>
            <element title="{.}" href="{@href}"/>
           </xsl:for-each>
          </xsl:element>
         </xsl:for-each>
        </element>
     </xsl:for-each>
    </element>
  </root>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному XML-документу :

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  <head>
    <title>HTML Document Title</title>
  </head>
  <body>
    <h1>Welcome</h1>
    <div class="container">
      <ul>
        <li>
          <a href="a.html" title="abcdef AAA">New York</a>
        </li>
        <li>
          <a href="b.html" title="abcdef AAA">Los Angles</a>
        </li>
        <li>
          <a href="c.html" title="abcdef AAA">Alaska</a>
        </li>
        <li>
          <a href="d.html" title="abcdef BBB">Florida</a>
        </li>
        <li>
          <a href="e.html" title="zyxwvu AAA"><em>California</em></a>
        </li>
      </ul>
    </div>
  </body>
</html>

создает искомое, правильный результат :

<root>
   <element title="hard-coded title" href="hard-coded url">
      <element title="AAA" href="AAA.html">
         <abcdef>
            <element title="Alaska" href="c.html"/>
            <element title="Los Angles" href="b.html"/>
            <element title="New York" href="a.html"/>
         </abcdef>
         <zyxwvu>
            <element title="California" href="e.html"/>
         </zyxwvu>
      </element>
      <element title="BBB" href="BBB.html">
         <abcdef>
            <element title="Florida" href="d.html"/>
         </abcdef>
      </element>
   </element>
</root>

Объяснение : вложенная мюнхенская группировка с использованием сначала одиночного, а затем составного группового ключа.key

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