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 上正常运行)。
我有一个 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 上正常运行)。