Select 3 个元素使用带命名空间的 XPath 但按属性过滤(仅限 Firefox)

Select 3 elements using XPath with namespace but filter it by attribute (Firefox Only)

我有一个 Blog structure XML with namespaces. I don't have any problem printing all the posts title, date and content - 尽管它只能在 Firefox 上正常工作(仅在版本 35 上测试过)。

我的计划是添加一个 select 标签,以便用户可以按语言过滤 post。我尝试了 很多 种不同的方法,但其中 none 行得通。不确定是浏览器限制还是编码错误。

以下是三个主要文件:

虽然可以看到我的source code here,这里是主要的JS方法:

    function LoadXMLWithXPath() {                           // load post titles and content using XPath
        xmlDoc = loadXMLDoc();                              // get XML content
        var xml = xmlDoc.responseXML;

        var path = "//p:title|//p:content|//p:date";                 // get all titles and its content
        var addContent = "";

        if (typeof xml.evaluate !== 'undefined') {          // if XML is not null. Enough for most browsers.


            /*
             *  xml.evaluate ( xpathExpression, contextNode, namespaceResolver, resultType, result )
             */
            var result = xml.evaluate(path, xml,            // 'result' is a XPathResult object
             function (prefix) {
                 switch (prefix) {                          // namespace resolver
                     case 'b': return 'http://www.familiagrissi.com/blog';
                     case 'a': return 'http://www.familiagrissi.com/authors';
                     case 'p': return 'http://www.familiagrissi.com/posts';
                     default: null;
                 }
             }, XPathResult.ANY_TYPE, null);

            var nodes = xml.evaluate(path, xml,
             function (prefix) {
                 switch (prefix) {
                     case 'b': return 'http://www.familiagrissi.com/blog';
                     case 'a': return 'http://www.familiagrissi.com/authors';
                     case 'p': return 'http://www.familiagrissi.com/posts';
                     default: null;
                 }
             }, XPathResult.ANY_TYPE, null);

            var result = nodes.iterateNext();               // store the nodes content on the result object

            title = true;
            date = false;
            content = false;

            hr = 0;

            testing = "";

            while (result) {
                if (hr % 3 == 0) {
                    addContent += '';
                }

                if (title) {
                    addContent += "<b>Title: </b>" + (result.childNodes[0].nodeValue) + "<br />";
                    title = false;
                    date = true;
                } else if (date) {
                    addContent += "<b>Date: </b>" + (result.childNodes[0].nodeValue) + "<br />";
                    date = false;
                    content = true;
                } else if (content) {
                    addContent += "<div class='article'><p><b>Content: </b>" + (result.childNodes[0].nodeValue) + "<p></div>";
                    content = false;
                    title = true;
                }
                hr++;
                if (hr % 3 == 0) {
                    addContent += "<hr />";
                }

                result = nodes.iterateNext();
            }
        }
        else if (typeof xml.selectNodes !== 'undefined' && typeof xml.setProperty != 'undefined') {
            // For IE only
            xml.setProperty('SelectionLanguage', 'XPath');
            xml.setProperty('SelectionNamespaces', 'xmlns:p="http://www.familiagrissi.com/posts"');
            var nodes = xml.selectNodes(path);

            var nodes = xml.selectNodes(path);

            for (i = 0; i < nodes.length; i++) { addContent += nodes[i].childNodes[0].nodeValue + "<br><hr />"; }
        }

        document.getElementById("loadPathXML").innerHTML = addContent;
        document.getElementById("testing").innerHTML = testing;
    }

我迄今为止最成功的尝试是仅打印 post 的标题并按语言过滤:

        var language = "es";
        var path = "//p:title[@lang='" + language + "']";

但是,当将此方法与完整代码一起使用时,网站会过滤标题但会加载所有日期和内容。

我 运行 没有想法,所以非常欢迎任何想法。我将对其进行测试,post 此处显示结果。

有两个主要问题,与JavaScript无关。 我在 .xml 文件的第一行代码中遗漏了文件夹名称。下面以粗体显示。

<b:blog xmlns:b="http://www.familiagrissi.com/blog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.familiagrissi.com/blog/blog.xsd">

此外,我对 XML 文件的逻辑是错误的。我有以下结构:

<p:posts xmlns:p="http://www.familiagrissi.com/posts">
    <p:post id="P012">
        <p:title lang="es">Jorge Juan Crespo de la Serna</p:title>
        <p:author>Cristiano Maia</p:author>
        <p:date>2014-10-14</p:date>
        <p:content>Jorge Juan Crespo de la Serna (1887 – 24 julio de 19781 )...</p:content>
    </p:post>

    <p:post id="P011">
        <p:title lang="en">Lorem Ipsu</p:title>
        <p:author>Cristiano Maia</p:author>
        <p:date>2014-10-14</p:date>
        <p:content>Jorge Lorem IpsuLorem IpsuLorem Ipsude 19781 )...</p:content>
    </p:post>
</p:posts>

并且我试图用 lang="es" 过滤所有 posts,但不可能成为其他内容的兄弟。所以我将属性 lang 移动到父元素 p:post.

<p:posts xmlns:p="http://www.familiagrissi.com/posts">
    <p:post id="P012" lang="es">
        <p:title>Jorge Juan Crespo de la Serna</p:title>
        <p:author>Cristiano Maia</p:author>
        <p:date>2014-10-14</p:date>
        <p:content>Jorge Juan Crespo de la Serna (1887 – 24 julio de 19781 )...</p:content>
    </p:post>

    <p:post id="P011" lang="en">
        <p:title>Lorem Ipsu</p:title>
        <p:author>Cristiano Maia</p:author>
        <p:date>2014-10-14</p:date>
        <p:content>Jorge Lorem IpsuLorem IpsuLorem Ipsude 19781 )...</p:content>
    </p:post>
</p:posts>

现在我可以使用以下路径并且它工作正常:

var path = "//p:post[@lang='" + lang + "']/p:title|//p:post[@lang='" + lang + "']/p:content|//p:post[@lang='" + lang + "']/p:date";

不是最干净的代码,但可以完成工作。 可在此处找到实时(2015 年 1 月 22 日)示例:http://www.familiagrissi.com/blog/(但只能在 Firefox 上正常运行)。