没有特定属性的XSLT排序

时间:2015-12-22 17:47:21

标签: xml xslt

首先,祝大家节日快乐!好的,所以我最近开始了一个新项目,要求我使用大量的XML文件,大约20k行,并且难以使用,因为它没有排序,并且导致很多重复属性出现在节点中,我想要解决这个问题。使用XSLT + Notepad ++应该可以轻松实现这一点,但是当您不知道每个属性及其格式为$grid.jqGrid({ url:'xtras/Products.php', editurl:'xtras/Products.php', datatype: "json", mtype:'POST', colModel:[ {name:'Catalogue',index:'catalogue.Catalogue', width:100}, {name:'Artist',index:'catalogue.Artist', width:170}, {name:'Title',index:'catalogue.Title', width:200}, ... ], cmTemplate: {editable: true}, postData: { filters: JSON.stringify({ groupOp: "OR", rules: [ { field: "Catalogue", op: "cn", data: "<?php echo $search; ?>" }, { field: "Artist", op: "cn", data: "<?php echo $search; ?>" }, { field: "Title", op: "cn", data: "<?php echo $search; ?>" } ] }) }, search: true, searching: { multipleSearch: true, loadDefaults: false, sopt: ['eq','ne','cn','bw','bn','ge','le','lt','gt'], showQuery: false }, navOptions: { add: false, edit: false, refreshstate: "current" } ..... }).jqGrid("navGrid"); 时,我很难找到有关XSLT排序的信息。

文件的样子:

<property name="" />

我希望文件看起来像什么:

<Items>
     <item id="1">
          <prop name="c">
          <prop name="a">
          <event name="c">
          <event name="a">
          <prop class="b">
               <prop name="a">
               <prop name="c">
          </prop>
          <prop class="a">
               <prop name="b">
               <prop name="a">
          </prop>
     </item>
</items>

我只想根据属性的值来排序<Items> <item id="1"> <prop name="a"> <prop name="b"> <event name="a"> <event name="c"> <prop class="a"> <prop name="a"> <prop name="c"> </prop> <prop class="b"> <prop name="a"> <prop name="b"> </prop> </item> </items> ,然后在<prop name..>

中找出相同的内容

- 更新 - 好吧,所以我不想要实际xml的帖子部分,因为它通常很容易交换代码,但是我在过去的几个小时里玩这个并且似乎无法让它工作。

这里有三种不同类型的XML项目。

<prop class>

3 个答案:

答案 0 :(得分:1)

可能有以下几点:

<xsl:stylesheet>
  <xsl:template match="/">
    <xsl:for-each select="//item">
      <xsl:for-each select="prop">
        <xsl:sort select="@name | @class">

这可能不是你正在寻找的,但你的问题也有点模糊。不过,这应该会给你一个足够好的起点来构建你自己的解决方案。

答案 1 :(得分:1)

假设XSLT 2.0(需要Saxon 9,XmlPrime或其他XSLT 2.0处理器)和输入

<Items>
     <item id="1">
          <prop name="c"/>
          <prop name="a"/>
          <event name="c"/>
          <event name="a"/>
          <prop class="b">
               <prop name="a"/>
               <prop name="c"/>
          </prop>
          <prop class="a">
               <prop name="b"/>
               <prop name="a"/>
          </prop>
     </item>
</Items>

代码

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

<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* , node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="item[prop] | prop[prop]">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:for-each-group select="*" group-adjacent="node-name(.)">
      <xsl:apply-templates select="current-group()">
        <xsl:sort select="@*"/> <!-- if there can be more than one attribute on a single child make that select="@name | @class" -->
      </xsl:apply-templates>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

创建结果

<Items>
   <item id="1">
      <prop name="a"/>
      <prop name="c"/>
      <event name="a"/>
      <event name="c"/>
      <prop class="a">
         <prop name="a"/>
         <prop name="b"/>
      </prop>
      <prop class="b">
         <prop name="a"/>
         <prop name="c"/>
      </prop>
   </item>
</Items>

根据您的新样本,执行工作的模板将更改为

<xsl:template match="block[property] | property[property]">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:for-each-group select="*" group-adjacent="node-name(.)">
      <xsl:apply-templates select="current-group()">
        <xsl:sort select="@name | @class"/>
      </xsl:apply-templates>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

答案 2 :(得分:0)

如果要对<prop>节点内的<item>节点进行排序,还要对<prop>节点内的<prop class="...">节点进行排序,这是一种方法:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" version="1.0" encoding="ISO-8859-1"/>

<xsl:template match="Items">
<root>
    <xsl:apply-templates select="item">
    </xsl:apply-templates>
</root>
</xsl:template>

<xsl:template match="item">
    <item id="{@id}">
    <xsl:apply-templates select="prop">
        <xsl:sort select="@name" data-type="text" order="ascending"/>
    </xsl:apply-templates>
    <xsl:apply-templates select="event"/>
    </item>
</xsl:template>

<xsl:template match="prop|event">
    <xsl:if test="@class">
        <prop class="{@class}">
            <xsl:apply-templates select="prop">
                <xsl:sort select="@name" data-type="text" order="ascending"/>
            </xsl:apply-templates>
        </prop>
    </xsl:if>
    <xsl:if test="not(@class)">
        <xsl:copy-of select="."/>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>