如何根据子节点值以降序获取xml文件的html表

时间:2014-12-28 00:39:12

标签: html xml sorting xslt

如何读取xml文件并按特定节点的数字顺序将其打印为html表?我尝试过并试过很多不同的方法。 xsl,xslt,jquery在渲染后对它进行排序,我疯了。

我需要按照最高点的顺序在html表中列出人员,目前它与我需要的相反。

我的xml文件如下

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="reverse.xsl"?>
<POSTS>
  <D>
    <TITLE>#bono</TITLE>
    <POINTS>1</POINTS>
  </D>
  <D>
    <TITLE>#justinbieber</TITLE>
    <POINTS>1</POINTS>
  </D>
  <D>
    <TITLE>#katiehopkins</TITLE>
    <POINTS>1</POINTS>
  </D>
  <D>
    <TITLE>#georgebush</TITLE>
    <POINTS>2</POINTS>
  </D>
</POSTS> 

我的HTML是......

<script>

if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.open("GET","https://dl.dropboxusercontent.com/u/434002/output.xml",false);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;


document.write("<thead><table id='myTable' class='tablesorter'><tr><th>POINTS</th>    <th>D</th></tr></thead><tbody>");
var x=xmlDoc.getElementsByTagName("D");
for (i=0;i<x.length;i++)
  {
  document.write("<tr><td><h2>");

  document.write(x[i].getElementsByTagName("POINTS")[0].childNodes[0].nodeValue);

  document.write("</h2></td><td><h2>");

  document.write(x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue);

  document.write("</h2></td></tr>");
  }
document.write("</table>");
</script>

这是我的xsl文件......

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

<xsl:template match="/POSTS/D">

   <xsl:for-each select="descendant-or-self::*/POINTS">

      <xsl:sort select="position()" data-type="number" order="descending"/>

    <xsl:value-of select="@id"/>

  </xsl:for-each>

</xsl:template>

</xsl:stylesheet>

任何帮助都会非常感激!谢谢

2 个答案:

答案 0 :(得分:0)

不确定这是否适合你 - 省略了js-part,这个XSL

<xsl:template match="POSTS">
<table>
<xsl:for-each select="D">
  <xsl:sort select="position()" data-type="number" order="descending"/>
  <tr>
   <td>
     <xsl:value-of select="POINTS"/>
   </td>
   <td>
    <xsl:value-of select="TITLE"/>
   </td>
  </tr>
 </xsl:for-each>
</table>
</xsl:template>

当应用于您的输入时,XML具有结果

<table>
  <tr>
    <td>2</td>
    <td>#georgebush</td>
  </tr>
  <tr>
    <td>1</td>
    <td>#katiehopkins</td>
  </tr>
  <tr>
    <td>1</td>
    <td>#justinbieber</td>
  </tr>
  <tr>
    <td>1</td>
    <td>#bono</td>
  </tr>
</table>

因此,如果您相应地调整XSL(模板匹配模式和xsl:for-each),它也可以为您服务。

更新:对于评论中的问题 - 这是一个直接的XSL转换 - xml到(在本例中为xml,也可能是html)xml。只是使用这个模板来转换你的xml与在线XSLT处理器 - http://xsltransform.net/ - 作为例子,并认为你可以相应地调整你的XSL部分。因为你的js似乎处理了XSL转换的output.xml:这个XSL

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <xsl:template match="POSTS">
   <POSTS>
     <xsl:for-each select="D">
      <xsl:sort select="position()" data-type="number" order="descending"/>
        <xsl:copy-of select="."/>
      </xsl:for-each>
    </POSTS>
  </xsl:template>
</xsl:stylesheet>

当应用于您的输入XML时,只需撤消订单,输出:

<POSTS>
  <D>
    <TITLE>#georgebush</TITLE>
    <POINTS>2</POINTS>
  </D>
  <D>
    <TITLE>#katiehopkins</TITLE>
    <POINTS>1</POINTS>
  </D>
  <D>
    <TITLE>#justinbieber</TITLE>
    <POINTS>1</POINTS>
  </D>
  <D>
    <TITLE>#bono</TITLE>
    <POINTS>1</POINTS>
  </D>
</POSTS>

更新2:正如评论中所提到的,OP从未使用过XSL,因此采用纯jQuery方法对XML进行排序可能会更好。调整后的脚本部分:

$(document).ready(function () {
  if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
  }
  else
  {// code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
  xmlhttp.open("GET","output.xml",false);
  xmlhttp.send();
  xmlDoc=xmlhttp.responseXML;

  var results = [];  // create an empty array

  $(xmlDoc).find('D').each(function() {  //select all D nodes
  var dName = $(this).find('TITLE').text(),
    dVal = $(this).find('POINTS').text();
    results.push({    // add the title and points as objects to the array
      title: dName,
      points: dVal
    });
  });

  results.sort(function(a, b) {   // now sort the array based on the points
    return parseInt(a.points) < parseInt(b.points);
  });

  var sorted=[];  // created a second array for the sorted results
  $.each(results, function() {
     sorted.push('<tr><td>' + this.points + '</td><td>' + this.title + '</td></tr>')
  });

  // create and append the table
  var $table= $("<table id='myTable' class='tablesorter'>");
  var $thead = $("<thead>");
  var $theadRow = $("<tr><th>POINTS</th><th>D</th></tr>");
  $thead.append($theadRow);
  var $tbody = $("<tbody>");
  $tbody.append( sorted.join(''));
  $table.append($thead);
  $table.append($tbody);
  $('body').append($table);
});

由于有许多关于如何使用jquery对XML进行排序的参考文献,只有一个可能有用的链接:http://forum.jquery.com/topic/mind-freeze-read-xml-file-and-sort-it

答案 1 :(得分:0)

如果您想按点对帖子进行排序,为什么要按位置对点进行排序?我也没有在你的XSLT尝试中看到任何表格。尝试:

XSLT 1.0

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

<xsl:template match="/POSTS">
    <table>
        <xsl:for-each select="D">
            <xsl:sort select="POINTS" data-type="number" order="descending"/>
            <tr>
                <td><xsl:value-of select="TITLE"/></td>
                <td><xsl:value-of select="POINTS"/></td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

这样你就不依赖于正在排序的输入。