用于根据多个值解析XML的XPath表达式?

时间:2012-03-08 15:42:02

标签: javascript html xml xslt xpath

这是我被困的地方(看看下面的文件以获得更好的图片):

value.singleNodeValue.setAttribute("select", "books/scifi[year>1962]");

如何在上面添加更多“过滤器”?例如:[year>1962 && author=Dan Larson]我知道这不是正确的语法,因为它不起作用,所以我该怎么做?

XML文件:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="books.xsl"?>
<!DOCTYPE books [
<!ENTITY Aring  "&amp;#197;" >
<!ENTITY aring  "&amp;#229;" >
<!ENTITY agrave "&amp;#224;" >
<!ENTITY aacute "&amp;#225;" >
<!ENTITY auml   "&amp;#228;" >
<!ENTITY ccedil "&amp;#231;" >
<!ENTITY eacute "&amp;#233;" >
<!ENTITY egrave "&amp;#232;" >
<!ENTITY iacute "&amp;#237;" >
<!ENTITY iuml   "&amp;#239;" >
<!ENTITY oacute "&amp;#243;" >
<!ENTITY ocirc  "&amp;#244;" >
<!ENTITY oslash "&amp;#248;" >
<!ENTITY Ouml   "&amp;#214;" >
<!ENTITY ouml   "&amp;#246;" >
<!ENTITY uuml   "&amp;#252;" >
]>

<books>

  <scifi key="DanlarsC83">
    <shelfcode>scif/all/83</shelfcode>
    <author>Dan Larson</author>,
    <author>James Roberts</author>,
    <author>Chris Rupert</author>,
    <title>The Game</title>,
    <pages>126-212</pages>,
    <year>1965</year>,
    <booktitle>SCI</booktitle>,
  </scifi>

  <scifi key="RobDwightS45">
    <shelfcode>scif/all/45</shelfcode>
    <author>Dan Larson</author>,
    <author>Christine Dwight</author>,
    <title>Hopes</title>,
    <pages>113-242</pages>,
    <year>1973</year>,
    <booktitle>SCI</booktitle>,
  </scifi>

  <scifi key="MarkJohnsC52">
    <shelfcode>scif/all/52</shelfcode>
    <author>Dan Larson</author>,
    <title>Incognitum</title>,
    <pages>131-420</pages>,
    <year>1949</year>,
    <booktitle>SCI</booktitle>,
  </scifi>

 </books>

XSL文件:

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

<xsl:template match="/">
  <html>
  <body>
    <center><h1>TOM's Sci-Fi</h1>
    <table border="1">
    <tr>
      <th>Title</th>
      <th>Authors</th>
      <th>Pages</th>
      <th>Year</th>
    </tr>
      <xsl:for-each select="books/scifi">
      <xsl:sort select="year"/>
    <tr>
      <td><center><xsl:value-of select="title"/></center></td>
      <td>
       <xsl:for-each select="author">
        <p><xsl:value-of select="."/></p>
        </xsl:for-each>
      </td> 
      <td><xsl:value-of select="pages"/></td>
      <td><xsl:value-of select="year"/></td>
    </tr>
    </xsl:for-each>
    </table>
    </center>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

HTML文件:

<html>

<script type="text/javascript">

var moz = (typeof document.implementation.createDocument != 'undefined');
var ie =  (typeof window.ActiveXObject != 'undefined');

function loadXML(file)
{
  var xmlDoc;
  if (moz)
    xmlDoc = document.implementation.createDocument("", "", null);
  else if (ie)
    xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
  xmlDoc.async = false;
  xmlDoc.validateOnParse=false;
  xmlDoc.load(file);
  return xmlDoc;
}
</script>

<body id="target4">
<script type="text/javascript">

 function filterTable(f)


{
  var xmlDoc = loadXML("books.xml");
  var stylesheet = loadXML("books.xsl");
  var moz = (typeof document.implementation.createDocument != 'undefined');
  var ie = (typeof window.ActiveXObject != 'undefined');

  if (moz)
  {
    var nsResolver = stylesheet.createNSResolver( stylesheet.ownerDocument == null ? stylesheet.documentElement : stylesheet.ownerDocument.documentElement);

    var value = stylesheet.evaluate("//xsl:template[@match='/']//xsl:for-each", stylesheet, nsResolver, XPathResult.ANY_UNORDERED_NODE_TYPE, null);

    var author = document.getElementById("inauthor").value;
    var title = document.getElementById("intitle").value;
    var year = document.getElementById("inyear").value;
    var filter = "";

    if (author != "")
    {
       filter= filter + "author='" + author.substr(1) + "'";
    }

    if (title != "")
    {
        if (filter != "") filter = filter + " and ";
        filter = filter + "title='" + title.substr(1) + "'";
    }

    if (year != "")
    {
        if (filter != "") filter = filter + " and ";
        filter = filter + "year" + year.substr(0) + year.substr(1);
    }

    value.singleNodeValue.setAttribute("select", "books/scifi[filter]");

    var proc = new XSLTProcessor();
    proc.importStylesheet(stylesheet);
    var resultFragment = proc.transformToFragment(xmlDoc, document);
    document.getElementById("target4").appendChild(resultFragment);
  }

  else if (ie)
  {

    var value = stylesheet.selectSingleNode("//xsl:template[@match='/']//xsl:for-each");

    value.setAttribute("select", "books/scifi[filter]");

    document.write(xmlDoc.transformNode(stylesheet));
  }
  }

<center>
  <table border="1" cellpadding="8">
  <tr><td>
  </br>
    <form>
      <center>
        <b> search by </b>
        Author(s): <input type="text" name="authors" />
        Title: <input type="text" name="title" />
        Year: <input type="text" name="year" />
        No of Authors: <input type="text" name="numauth" />
        </br></br>
        <b> sort by</b>
        <input type="radio" name="sorter" value="author" />author
        <input type="radio" name="sorter" value="title" />title
        <input type="radio" name="sorter" value="year" />year
        <input type="radio" name="sorter" value="pages" />pages</br></br>
        <input type="button" value="Display" onClick="filterTable(this.form)"/>
     </center>
    </form>
   </td></tr>
   </table>
</center>

</body>

</html>

1 个答案:

答案 0 :(得分:1)

[year>1962 and author='Dan Larson']

根据用户选择的值动态设置值:

  1. 为输入提供ID(例如<input type="text name="authors" id="author">)。
  2. 使用以下代码
  3. (这未经过测试!)

    var author = document.getElementById("author").value;
    var title = document.getElementById("title").value;
    var year = document.getElementById("year").value;
    
    var filter = "";
    if (authors != "") filter += "author='" + author + "'";
    if (title != "") {
        if (filter != "") filter += " and ";
        filter += "title='" + title + "'";
    }
    if (year != "") {
        if (filter != "") filter += " and ";
        filter += "year>" + year;
    }
    if (filter != "") filter = "[" + filter + "]";
    
    value.setAttribute("select", "books/scifi" + filter);