How to select tags with namespaces in CasperJS?

烈酒焚心 提交于 2019-12-25 06:47:30

问题


I'm refactoring a RSS so I decided to write some tests with CasperJS.

One of the elements of the RSS is "atom:link" (")

I tried this three codes, but none works

test.assertExists("//atom:link", "atom:link tag exists.");

test.assertExists({
    type: 'xpath',
    path: "//atom:link"
}, "atom:link element exists.");

//even this...
test.assertExists({
    type: 'xpath',
    namespace: "xmlns:atom",
    path: "//atom:link"
}, "atom:link element exists.");

The RSS code is:

<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xml:base="http://example.org/" xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/"
     xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>RSS Title</title>
        <description>RSS description</description>
        <link>http://example.org</link>
        <lastBuildDate>Mon, 10 Nov 2014 11:37:02 +0000</lastBuildDate>
        <language>es-ES</language>
        <atom:link rel="self" href="http://example.org/rss/feed.xml"/>
        <item></item>
        <item></item>
    </channel>
</rss>

I saw that in a demo in this page http://www.freeformatter.com/xpath-tester.html, foo:singers is accesible by:

//foo:singers

But in CasperJS seems that this don't work...

Anyone know how to select this kind of elements with a namespace?


回答1:


The function which CasperJS uses to resolve elements by XPath is document.evaluate:

var xpathResult = document.evaluate(
 xpathExpression, 
 contextNode, 
 namespaceResolver, 
 resultType, 
 result
);

When you look into the source code the namespaceResolver is always null. That means that CasperJS cannot use XPaths with prefixes. If you try it, you get

[error] [remote] findAll(): invalid selector provided "xpath selector: //atom:link":Error: NAMESPACE_ERR: DOM Exception 14

You would have to create your own method to retrieve elements with a user defined nsResolver.

casper.myXpathExists = function(selector){
    return this.evaluate(function(selector){
        function nsResolver(prefix) {
            var ns = {
                'atom' : 'http://www.w3.org/2005/Atom'
            };
            return ns[prefix] || null;
        }
        return !!document.evaluate(selector, 
                document, 
                nsResolver, 
                XPathResult.ANY_TYPE, 
                null).iterateNext(); // retrieve first element
    }, selector);
};
// and later
test.assertTrue(casper.myXpathExists("//atom:link"), "atom:link tag exists.");


来源:https://stackoverflow.com/questions/26931073/how-to-select-tags-with-namespaces-in-casperjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!