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

时间:2015-01-19 23:14:04

标签: xml xpath xsd namespaces

我有Blog structure XML个名称空间。我没有任何问题printing all the posts title, date and content - 虽然它只适用于Firefox(仅在第35版上测试过)。

我的计划是添加选择标记,以便用户可以按语言过滤帖子。我尝试过很多不同的东西,但都没有。不确定是否存在浏览器限制或编码错误。

以下是三个主要文件:

虽然你可以看到我的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;
    }

到目前为止,我最成功的尝试是仅打印帖子标题并按语言过滤:

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

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

我已经没有想法了,所以任何想法都非常受欢迎。我将测试它并在此处发布结果。

1 个答案:

答案 0 :(得分:0)

有两个主要问题,与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 =&#34; es&#34;来过滤所有帖子,但它不可能成为其他内容的兄弟。所以我将属性 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)。