xml – 从XSLT中的路径创建嵌套树结构

我有一个动态的 XML文档,它表示一个类别的树结构,但这样做是以任意顺序使用路径分隔的属性,如下所示:
<data>    
      <record ID="24" Name="category 1\sub category 1"/>   
      <record ID="26" Name="category 1"/>     
      <record ID="25" Name="category 1\sub category 1\sub category 2"/>    
      <record ID="27" Name="category 1\sub category 1\sub category 3"/>    
      ...
   </data>

我需要提出一个解决方案,使XML标准化,以便将其转换成如下所示:

<data>    
      <record ID="26" Name="category 1">    
         <record ID="24" Name="sub category 1">    
            <record ID="25" Name="sub category 2"/>
            <record ID="27" Name="sub category 3"/>    
         </record>
      </record>   
      ...
   </data>

基本上我想知道这是否是XSLT可能解决的问题,以及如何,而不是以编程方式进行.

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

  <xsl:output indent="yes" />

  <xsl:template match="/data">
    <!-- copy the document element -->
    <xsl:copy>
      <!-- That's where we start: all "record" nodes that have no "\". -->
      <xsl:apply-templates mode="recurse" select="/data/record[
        not(contains(@Name,'\'))
      ]" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="record" mode="recurse">
    <xsl:param name="starting-path" select="''" />

    <!-- The record node and its ID attribute can be copied. --> 
    <xsl:copy>
      <xsl:copy-of select="@ID" />

      <!-- Create the new "name" attribute. -->
      <xsl:attribute name="Name">
        <xsl:value-of select="substring-after(@Name,$starting-path)" />
      </xsl:attribute>

      <!-- Append a backslash to the current path. -->
      <xsl:variable name="current-path" select="concat(@Name,'\')" />

      <!-- Select all "record" nodes that are one level deeper... -->
      <xsl:variable name="children" select="/data/record[
        starts-with(@Name,$current-path)
        and
        not(contains(substring-after(@Name,$current-path),'\'))
      ]" />

      <!-- ...and apply this template to them. -->
      <xsl:apply-templates mode="recurse" select="$children">
        <xsl:with-param name="starting-path" select="$current-path" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

我的系统输出:

<data>
  <record ID="26" Name="category 1">
    <record ID="24" Name="sub category 1">
      <record ID="25" Name="sub category 2"></record>
      <record ID="27" Name="sub category 3"></record>
    </record>
  </record>
</data>

请注意,整个解决方案是基于以下假设:所有路径都是规范的,不包含尾随的反斜杠.

还要注意,任何不匹配的/孤立的“记录”元素都不会在输出中(除非当然是根级别).

还有一件事:模板模式(“递归”)并不是绝对必要的.我包括它,因为模板正在做一些比较特别的事情,并且可能有机会在你的解决方案中有一个匹配“记录”节点的模板.在这种情况下,这个解决方案可以放在没有任何其他的东西.对于独立解决方案,可以随时删除模板模式.

呵呵,最后一件事情是:如果你希望结果文件按照Name命名,请使用< xsl:apply-templates> (两次出现),像这样:

<xsl:apply-templates select="...">
  <xsl:sort select="@Name" data-type="text" order="ascending" />
</xsl:apply-templates>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类
XML入门的常见问题(二)
Java对象的强、软、弱和虚引用
JS解析XML文件和XML字符串详解
java中枚举的详细使用介绍
了解Xml格式
XML入门的常见问题(四)
深入SQLite多线程的使用总结详解
PlayFramework完整实现一个APP(一)
XML和YAML的使用方法
XML轻松学习总节篇