Html 如何使用XSLT从XML数据创建TreeView

Html 如何使用XSLT从XML数据创建TreeView,html,xml,xslt,treeview,grouping,Html,Xml,Xslt,Treeview,Grouping,我有以下格式的XML数据: <table> <col> <name>Addresses</name> </col> <col> <name>Addresses/Address1</name> </col> <col> <name>Addresses/Address2</name> </col> <col>

我有以下格式的XML数据:

<table>
 <col>
  <name>Addresses</name>
 </col>
 <col>
  <name>Addresses/Address1</name>
 </col>
 <col>
  <name>Addresses/Address2</name>
 </col>
 <col>
  <name>Addresses/Address1/Flat Number</name>
 </col>
 <col>
  <name>Employee Name</name>
 </col>
 <col>
  <name>Phone Number</name>
 </col>
 <col>
  <name>Profession</name>
 </col>
 <col>
  <name>Employee Name/First Name</name>
 </col>
 <col>
  <name>Employee Name/Last Name</name>
 </col>
 <col>
  <name>Employee Name/First_Name</name>
 </col>
 <col>
  <name>Accounts/Account Name/First/Saving</name>
 </col>
 <col>
  <name>Accounts/Account_Name/Second</name>
 </col>
</table> 

地址
地址/地址1
地址/地址2
地址/地址1/固定号码
员工姓名
电话号码
职业
员工姓名
员工姓名
员工姓名
帐户/帐户名/第一个/保存
账户/账户名称/秒
现在我想在这个XML上使用XSLT在HTML中创建一个类似treeview的结构。Treeview的结构类似于以下结构:

  • 地址
    • 地址1
    • 地址2
  • 员工姓名
    • 名字
  • 帐目
    • 帐户名
请注意,第一次出现“/”之前的子串是树视图的第一级节点,“/”第一次出现之后的子串是匹配的第一级节点的第二级节点,这只是一个2级树视图

此外,显示的值是唯一的。即使这些值在XML中重复,我们也只需要选择一个唯一的值。另一个要考虑的条件是,与“例如”和“FrestTyN名字”一样,“与”相同的值被认为与“没有”相同,因此我们需要在“--”与“.< /P>”替换后显示值。

问题是,这段代码的输出如下

  • 地址
      • -
    • 地址1
    • 地址2
  • 员工姓名
      • -
    • 名字
    • 名字
  • 帐目
    • 帐户名
    • 帐户名
请帮我解决这个问题


提前感谢。

此XSLT 1.0转换:

<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:key name="kCatFromName" match="name"
      use="substring-before(concat(.,'/'), '/')"/>

     <xsl:key name="kValFromName" match="name[contains(., '/')]"
      use="concat(substring-before(.,'/'),
           '+',
           translate(
               substring-before
                 (concat(substring-after(.,'/'), '/'),
                  '/'
                 ),
               '_',
               ' '
                       )
                )
          "/>

     <xsl:template match="/*">
      <ul>
         <xsl:apply-templates mode="cat" select=
          "*/name
             [generate-id()
             =
              generate-id(key('kCatFromName',
                               substring-before(concat(.,'/'), '/')
                               )[1]
                        )
             ]
          "/>
        </ul>
     </xsl:template>

     <xsl:template match="name" mode="cat">
      <xsl:variable name="vCat" select=
      "substring-before(concat(.,'/'), '/')"/>
      <li><xsl:value-of select="$vCat"/></li>

       <xsl:variable name="vInThisCat" select=
       "key('kCatFromName', $vCat)
         [generate-id()
         =
          generate-id(key('kValFromName',
                          concat(substring-before(.,'/'),
                                 '+',
                                 translate(
                                           substring-before
                                            (concat(substring-after(.,'/'), '/'),
                                             '/'
                                            ),
                                            '_',
                                            ' '
                                            )
                                )
                          )[1]
                      )
         ]"/>

         <xsl:if test="$vInThisCat">
        <ul>
          <xsl:apply-templates mode="val" select="$vInThisCat"/>
         </ul>
       </xsl:if>
     </xsl:template>

      <xsl:template match="name" mode="val">
        <li>
          <xsl:value-of select=
          "translate(substring-before
                (concat(substring-after(.,'/'), '/'),
                 '/'
                ),
               '_',
               ' '
               )
          "/>
        </li>
      </xsl:template>
</xsl:stylesheet>
<table>
    <col>
        <name>Addresses</name>
    </col>
    <col>
        <name>Addresses/Address1</name>
    </col>
    <col>
        <name>Addresses/Address2</name>
    </col>
    <col>
        <name>Addresses/Address1/Flat Number</name>
    </col>
    <col>
        <name>Employee Name</name>
    </col>
    <col>
        <name>Phone Number</name>
    </col>
    <col>
        <name>Profession</name>
    </col>
    <col>
        <name>Employee Name/First Name</name>
    </col>
    <col>
        <name>Employee Name/Last Name</name>
    </col>
    <col>
        <name>Employee Name/First_Name</name>
    </col>
    <col>
        <name>Accounts/Account Name/First/Saving</name>
    </col>
    <col>
        <name>Accounts/Account_Name/Second</name>
    </col>
</table>
<ul>
   <li>Addresses</li>
   <ul>
      <li>Address1</li>
      <li>Address2</li>
   </ul>
   <li>Employee Name</li>
   <ul>
      <li>First Name</li>
      <li>Last Name</li>
   </ul>
   <li>Phone Number</li>
   <li>Profession</li>
   <li>Accounts</li>
   <ul>
      <li>Account Name</li>
   </ul>
</ul>

  • 应用于提供的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:key name="kCatFromName" match="name"
          use="substring-before(concat(.,'/'), '/')"/>
    
         <xsl:key name="kValFromName" match="name[contains(., '/')]"
          use="concat(substring-before(.,'/'),
               '+',
               translate(
                   substring-before
                     (concat(substring-after(.,'/'), '/'),
                      '/'
                     ),
                   '_',
                   ' '
                           )
                    )
              "/>
    
         <xsl:template match="/*">
          <ul>
             <xsl:apply-templates mode="cat" select=
              "*/name
                 [generate-id()
                 =
                  generate-id(key('kCatFromName',
                                   substring-before(concat(.,'/'), '/')
                                   )[1]
                            )
                 ]
              "/>
            </ul>
         </xsl:template>
    
         <xsl:template match="name" mode="cat">
          <xsl:variable name="vCat" select=
          "substring-before(concat(.,'/'), '/')"/>
          <li><xsl:value-of select="$vCat"/></li>
    
           <xsl:variable name="vInThisCat" select=
           "key('kCatFromName', $vCat)
             [generate-id()
             =
              generate-id(key('kValFromName',
                              concat(substring-before(.,'/'),
                                     '+',
                                     translate(
                                               substring-before
                                                (concat(substring-after(.,'/'), '/'),
                                                 '/'
                                                ),
                                                '_',
                                                ' '
                                                )
                                    )
                              )[1]
                          )
             ]"/>
    
             <xsl:if test="$vInThisCat">
            <ul>
              <xsl:apply-templates mode="val" select="$vInThisCat"/>
             </ul>
           </xsl:if>
         </xsl:template>
    
          <xsl:template match="name" mode="val">
            <li>
              <xsl:value-of select=
              "translate(substring-before
                    (concat(substring-after(.,'/'), '/'),
                     '/'
                    ),
                   '_',
                   ' '
                   )
              "/>
            </li>
          </xsl:template>
    </xsl:stylesheet>
    
    <table>
        <col>
            <name>Addresses</name>
        </col>
        <col>
            <name>Addresses/Address1</name>
        </col>
        <col>
            <name>Addresses/Address2</name>
        </col>
        <col>
            <name>Addresses/Address1/Flat Number</name>
        </col>
        <col>
            <name>Employee Name</name>
        </col>
        <col>
            <name>Phone Number</name>
        </col>
        <col>
            <name>Profession</name>
        </col>
        <col>
            <name>Employee Name/First Name</name>
        </col>
        <col>
            <name>Employee Name/Last Name</name>
        </col>
        <col>
            <name>Employee Name/First_Name</name>
        </col>
        <col>
            <name>Accounts/Account Name/First/Saving</name>
        </col>
        <col>
            <name>Accounts/Account_Name/Second</name>
        </col>
    </table>
    
    <ul>
       <li>Addresses</li>
       <ul>
          <li>Address1</li>
          <li>Address2</li>
       </ul>
       <li>Employee Name</li>
       <ul>
          <li>First Name</li>
          <li>Last Name</li>
       </ul>
       <li>Phone Number</li>
       <li>Profession</li>
       <li>Accounts</li>
       <ul>
          <li>Account Name</li>
       </ul>
    </ul>
    
    
    地址
    地址/地址1
    地址/地址2
    地址/地址1/固定号码
    员工姓名
    电话号码
    职业
    员工姓名
    员工姓名
    员工姓名
    帐户/帐户名/第一个/保存
    账户/账户名称/秒
    
    生成所需的正确结果

    <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:key name="kCatFromName" match="name"
          use="substring-before(concat(.,'/'), '/')"/>
    
         <xsl:key name="kValFromName" match="name[contains(., '/')]"
          use="concat(substring-before(.,'/'),
               '+',
               translate(
                   substring-before
                     (concat(substring-after(.,'/'), '/'),
                      '/'
                     ),
                   '_',
                   ' '
                           )
                    )
              "/>
    
         <xsl:template match="/*">
          <ul>
             <xsl:apply-templates mode="cat" select=
              "*/name
                 [generate-id()
                 =
                  generate-id(key('kCatFromName',
                                   substring-before(concat(.,'/'), '/')
                                   )[1]
                            )
                 ]
              "/>
            </ul>
         </xsl:template>
    
         <xsl:template match="name" mode="cat">
          <xsl:variable name="vCat" select=
          "substring-before(concat(.,'/'), '/')"/>
          <li><xsl:value-of select="$vCat"/></li>
    
           <xsl:variable name="vInThisCat" select=
           "key('kCatFromName', $vCat)
             [generate-id()
             =
              generate-id(key('kValFromName',
                              concat(substring-before(.,'/'),
                                     '+',
                                     translate(
                                               substring-before
                                                (concat(substring-after(.,'/'), '/'),
                                                 '/'
                                                ),
                                                '_',
                                                ' '
                                                )
                                    )
                              )[1]
                          )
             ]"/>
    
             <xsl:if test="$vInThisCat">
            <ul>
              <xsl:apply-templates mode="val" select="$vInThisCat"/>
             </ul>
           </xsl:if>
         </xsl:template>
    
          <xsl:template match="name" mode="val">
            <li>
              <xsl:value-of select=
              "translate(substring-before
                    (concat(substring-after(.,'/'), '/'),
                     '/'
                    ),
                   '_',
                   ' '
                   )
              "/>
            </li>
          </xsl:template>
    </xsl:stylesheet>
    
    <table>
        <col>
            <name>Addresses</name>
        </col>
        <col>
            <name>Addresses/Address1</name>
        </col>
        <col>
            <name>Addresses/Address2</name>
        </col>
        <col>
            <name>Addresses/Address1/Flat Number</name>
        </col>
        <col>
            <name>Employee Name</name>
        </col>
        <col>
            <name>Phone Number</name>
        </col>
        <col>
            <name>Profession</name>
        </col>
        <col>
            <name>Employee Name/First Name</name>
        </col>
        <col>
            <name>Employee Name/Last Name</name>
        </col>
        <col>
            <name>Employee Name/First_Name</name>
        </col>
        <col>
            <name>Accounts/Account Name/First/Saving</name>
        </col>
        <col>
            <name>Accounts/Account_Name/Second</name>
        </col>
    </table>
    
    <ul>
       <li>Addresses</li>
       <ul>
          <li>Address1</li>
          <li>Address2</li>
       </ul>
       <li>Employee Name</li>
       <ul>
          <li>First Name</li>
          <li>Last Name</li>
       </ul>
       <li>Phone Number</li>
       <li>Profession</li>
       <li>Accounts</li>
       <ul>
          <li>Account Name</li>
       </ul>
    </ul>
    
    • 地址
      • 地址1
      • 地址2
    • 员工姓名
      • 名字
    • 电话号码
    • 职业
    • 帐目
      • 帐户名
    并在浏览器中显示为

    <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:key name="kCatFromName" match="name"
          use="substring-before(concat(.,'/'), '/')"/>
    
         <xsl:key name="kValFromName" match="name[contains(., '/')]"
          use="concat(substring-before(.,'/'),
               '+',
               translate(
                   substring-before
                     (concat(substring-after(.,'/'), '/'),
                      '/'
                     ),
                   '_',
                   ' '
                           )
                    )
              "/>
    
         <xsl:template match="/*">
          <ul>
             <xsl:apply-templates mode="cat" select=
              "*/name
                 [generate-id()
                 =
                  generate-id(key('kCatFromName',
                                   substring-before(concat(.,'/'), '/')
                                   )[1]
                            )
                 ]
              "/>
            </ul>
         </xsl:template>
    
         <xsl:template match="name" mode="cat">
          <xsl:variable name="vCat" select=
          "substring-before(concat(.,'/'), '/')"/>
          <li><xsl:value-of select="$vCat"/></li>
    
           <xsl:variable name="vInThisCat" select=
           "key('kCatFromName', $vCat)
             [generate-id()
             =
              generate-id(key('kValFromName',
                              concat(substring-before(.,'/'),
                                     '+',
                                     translate(
                                               substring-before
                                                (concat(substring-after(.,'/'), '/'),
                                                 '/'
                                                ),
                                                '_',
                                                ' '
                                                )
                                    )
                              )[1]
                          )
             ]"/>
    
             <xsl:if test="$vInThisCat">
            <ul>
              <xsl:apply-templates mode="val" select="$vInThisCat"/>
             </ul>
           </xsl:if>
         </xsl:template>
    
          <xsl:template match="name" mode="val">
            <li>
              <xsl:value-of select=
              "translate(substring-before
                    (concat(substring-after(.,'/'), '/'),
                     '/'
                    ),
                   '_',
                   ' '
                   )
              "/>
            </li>
          </xsl:template>
    </xsl:stylesheet>
    
    <table>
        <col>
            <name>Addresses</name>
        </col>
        <col>
            <name>Addresses/Address1</name>
        </col>
        <col>
            <name>Addresses/Address2</name>
        </col>
        <col>
            <name>Addresses/Address1/Flat Number</name>
        </col>
        <col>
            <name>Employee Name</name>
        </col>
        <col>
            <name>Phone Number</name>
        </col>
        <col>
            <name>Profession</name>
        </col>
        <col>
            <name>Employee Name/First Name</name>
        </col>
        <col>
            <name>Employee Name/Last Name</name>
        </col>
        <col>
            <name>Employee Name/First_Name</name>
        </col>
        <col>
            <name>Accounts/Account Name/First/Saving</name>
        </col>
        <col>
            <name>Accounts/Account_Name/Second</name>
        </col>
    </table>
    
    <ul>
       <li>Addresses</li>
       <ul>
          <li>Address1</li>
          <li>Address2</li>
       </ul>
       <li>Employee Name</li>
       <ul>
          <li>First Name</li>
          <li>Last Name</li>
       </ul>
       <li>Phone Number</li>
       <li>Profession</li>
       <li>Accounts</li>
       <ul>
          <li>Account Name</li>
       </ul>
    </ul>
    
    • 地址
      • 地址1
      • 地址2
    • 员工姓名
      • 名字
    • 电话号码
    • 职业
    • 帐目
      • 帐户名

    您能否提供可能有效的示例xml!纳瓦切夫,非常感谢:)。。。您的xslt代码运行良好,但它显示的结果如下:
    • 地址
      • 地址1
      • 地址2
        • 。在第一个列表项停止后,什么也没有显示。此外,我还将我的订购清单计划为地址
          • 地址1
          • 地址2
              • 。。。你能帮我显示新的格式吗,还有所有的列表项,不仅仅是第一个。对不起,我的错,我遇到了问题,为什么你的代码不适合我,我正在更新XML,因为我们还没有考虑过更多的场景,然后我们可以再试一次以获得所需的结果。希望你这次也能帮助我。:)@manishekhawat:这段代码使用几个XSLT1.0处理器(MSXML3/4、.NET XSLCompletedTransform、Saxon 6.5.4和AltovaXML(XML-SPY))进行测试正确工作并产生相同的完整结果。如果您得到的结果不完整,可能是您更改了XML文档或XSLT代码,或者两者都更改了,或者您正在使用一个有缺陷的、不符合要求的XSLT处理器。@manishekhawat:最好提出一个新问题,而不是更新这个已经非常复杂的问题。这个问题已经解决了因此,请大家回答我的问题。我很乐意处理你的新问题。我已经更新了XML,我在没有“/”的情况下添加了两个新的COL标签。这也是treeview电话号码专业中没有二级节点的一级节点。我希望您在阅读了评论和新XML中的更新后,能够更好地了解这个问题,感谢您迄今为止对我的帮助,期待同样的结果:)