0

我在这里遇到了相当大的挑战...

是否有可能有一个适用于任何 XML 层次结构的 XSL 代码,将其转换为嵌套的 HTML 列表?

示例 XML:

<Base>
  <Parent>
    <Child />
    <Child>
      <ChildOne />
      <ChildOne>
       <ChildTwo />
       <ChildTwo />
      </ChildOne>
    </Child>
  </Parent>
  <Parent>
    <Child>
      <ChildOne>
        <ChildTwo>
          <ChildThree>
            <ChildFour />
          </ChildThree>
          <ChildThree/>
        </ChildTwo>
      </ChildOne>
      <ChildOne/>
      <ChildOne/>
    </Child>
    <Child/>
  </Parent>
</Base>

期望的结果:

<ul>
  <li>Parent1
    <ul>
      <li>Child</li>
      <li>Child
        <ul>
        <li>ChildOne</li>
        <li>ChildOne>
           <ul>
              <li>ChildTwo</li>
              <li>ChildTwo</li>
           </ul>
        </li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Parent2
    <ul>
      <li>Child
        <ul>
            <li>ChildOne
                <ul>
                    <li>ChildTwo
                  <ul>
                  <li>ChildThree
                     <ul>
                         <li>ChildFour</li>
                     </ul>
                  </li>
                  <li>ChildThree</li>
                  </ul>
                </li>
            </ul>
            </li>
            <li>ChildOne</li>
            <li>ChildOne</li>
         </ul>
       </li>
       <li>Child</li>
    </ul>
  </li>
</ul>

所以逻辑是,如果在元素(上 el.)下还有其他元素(被抑制的 el。) - 被抑制的 el。被包围<li>name of upper el.<ul>all suppressed el.</ul></li>等等。

我的观点是,这个 XSL 代码不是通过元素或属性的值或名称工作,而是通过条件检查,如果有其他元素属于特定元素。

Fe,如果ChildThree没有ChildFour在其下,它只是<li>ChildThree>代替

<li>ChildThree
   <ul>
      <li>ChildFour</li>
   </ul>
</li>

希望我解释清楚。:)

PS这或多或少是它在浏览器中的外观(只是为了提供视觉表示,因为我们人类喜欢看到这些东西。:P)

在此处输入图像描述

4

2 回答 2

3

使用样式表

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

<xsl:output method="html" indent="yes"/>

<xsl:template match="*[*]">
  <li>
    <xsl:value-of select="local-name()"/>
    <ul>
      <xsl:apply-templates/>
    </ul>
  </li>
</xsl:template>

<xsl:template match="*[not(*)]">
  <li>
    <xsl:value-of select="local-name()"/>
  </li>
</xsl:template>

<xsl:template match="/*" priority="5">
  <ul>
    <xsl:apply-templates/>
  </ul>
</xsl:template>

</xsl:stylesheet>

Saxon 6.5.5 转换输入

<Base>
  <Parent>
    <Child />
    <Child>
      <ChildOne />
      <ChildOne>
       <ChildTwo />
       <ChildTwo />
      </ChildOne>
    </Child>
  </Parent>
  <Parent>
    <Child>
      <ChildOne>
        <ChildTwo>
          <ChildThree>
            <ChildFour />
          </ChildThree>
          <ChildThree/>
        </ChildTwo>
      </ChildOne>
      <ChildOne/>
      <ChildOne/>
    </Child>
    <Child/>
  </Parent>
</Base>

进入结果

<ul>

   <li>Parent
      <ul>

         <li>Child</li>

         <li>Child
            <ul>

               <li>ChildOne</li>

               <li>ChildOne
                  <ul>

                     <li>ChildTwo</li>

                     <li>ChildTwo</li>

                  </ul>
               </li>

            </ul>
         </li>

      </ul>
   </li>

   <li>Parent
      <ul>

         <li>Child
            <ul>

               <li>ChildOne
                  <ul>

                     <li>ChildTwo
                        <ul>

                           <li>ChildThree
                              <ul>

                                 <li>ChildFour</li>

                              </ul>
                           </li>

                           <li>ChildThree</li>

                        </ul>
                     </li>

                  </ul>
               </li>

               <li>ChildOne</li>

               <li>ChildOne</li>

            </ul>
         </li>

         <li>Child</li>

      </ul>
   </li>

</ul>
于 2013-08-27T12:40:43.913 回答
1

这个 XSL 样式表可以满足您的需求。

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

  <!-- Match the Base element, with high priority to avoid matching the more
       specific template further down, that matches *[*] -->
  <xsl:template match="Base" priority="10">
    <ul>
      <xsl:apply-templates/>
    </ul>
  </xsl:template>

  <!-- Match the Parent element, with high priority to avoid matching the more
       specific template further down, that matches *[*] -->
  <xsl:template match="Parent" priority="10">
    <li>
      <!-- Output a Parent element and append it with its position amongst
           all Parent elements at this level. -->
      <xsl:text>Parent</xsl:text>
      <xsl:value-of select="count(preceding-sibling::Parent) + 1"/>
      <xsl:apply-templates/>
    </li>
  </xsl:template>

  <!-- Match those elements that have children. -->
  <xsl:template match="*[*]">
    <li>
      <xsl:value-of select="local-name(.)"/>
      <ul>
        <xsl:apply-templates/>
      </ul>
    </li>
  </xsl:template>

  <!-- Match the remaining elements (without children) -->
  <xsl:template match="*">
    <li>
      <xsl:value-of select="local-name(.)"/>
    </li>
  </xsl:template>
</xsl:stylesheet>

您可以在这里看到它的实际效果。

于 2013-08-27T12:42:12.007 回答