处理XHTML(格式良好的XML)无序列表数据到分组和排序的XML

时间:2011-09-20 13:46:08

标签: xml xslt

我需要将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>

注意:我注意到在XSLT解析期间使用DOCTYPE声明和简单注释会导致失败。所以,我在XSL解析之前手动删除它们。要正确解析输出,目前使用帖子提供的'xhtml:'前缀:Can I parse an HTML using XSLT?

根据标签标题值(子字符串第2部分)对元素进行分组,例如AAA,BBB等。进一步分组标题属性值的第一部分(例如abcdef / zyxwvu)或&lt; em&gt;的存在。标签。 总共有四个元素,例如&lt; root&gt;,&lt; element&gt;,&lt; abcdef&gt;和&lt; zyxwvu&gt;在输出中。这是理想的。

预期输出:

<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和XSL中都提供了解决方案,我们将不胜感激。 2.0。

1 个答案:

答案 0 :(得分:0)

此转化

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

解释:首先使用单个嵌套Muenchian分组,然后使用复合分组key.key