开发者

How to treat child nodes using libxmljs (Node.js)

I got confused when I tried to parse following xml using libxmljs:

<?xml version="1.0" encoding="UTF-8"?>
<ResultSet>
    <Result>
        <Title>Title 1</Title>
        <Summary>Summary 1</Summary>
    </Result>
    <Result>
        <Title>Title 2</Title>
        <Summary>Summary 2</Summary>
    </Result>
</ResultSet>

I tried following code:

var libxmljs = require("libxmljs");
var xmlDoc = libxmljs.parseXmlFile("sample.xml");
xmlDoc.root().childNodes().length; // 5

I thought length property of third line should be 2, because there are 2 Result nodes, which are children of root node.

By the way, I inspected each elements like:

xmlDoc.root().childNodes()[0].get("Title").text(); // TypeError: Cannot call method '开发者_开发知识库text' of undefined
xmlDoc.root().childNodes()[1].get("Title").text(); // Title 1
xmlDoc.root().childNodes()[2].get("Title").text(); // TypeError: Cannot call method 'text' of undefined
xmlDoc.root().childNodes()[3].get("Title").text(); // Title 2
xmlDoc.root().childNodes()[4].get("Title").text(); // TypeError: Cannot call method 'text' of undefined

Why there are some irrelevant child nodes? Thanks in advance!

(my libxmljs version is 0.4.2)


In case you can't remove the whitespace, you have two simple solutions:

Either check the type of each node before you use it:

xmlDoc.root().childNodes()[0].type() // 'text'

will be either 'text' or 'element'. You can ignore the text ones.

Better though is to use the xpath system. You can find all the actual elements thusly:

xmlDoc.find('*')[0].get('Title').text() // 'Title 1'

Or you can even just access the title nodes directly through xpath:

xmlDoc.find('*/Title')[0].text() // 'Title 1'


Raynos is correct. The 5 nodes you are seeing are . Try this version of your xml.

<?xml version="1.0" encoding="UTF-8"?>
<ResultSet><Result><Title>Title 1</Title><Summary>Summary 1</Summary></Result><Result><Title>Title 2</Title><Summary>Summary 2</Summary></Result></ResultSet>

And this returns nothing because the first child is a text node with no children.

xmlDoc.root().childNodes()[0].get("Title");

Most xml libs paper over the details and do "the sensible thing" like return only element nodes. Libxmljs is a loose wrapper around the libxml2 library. But libxml2 doesn't do that. So it helps to understand the libxml2 DOM model. In the XML standard for parsing into a DOM, text nodes are valid children just like elements. There are also entities, CDATA, etc. You have to deal with these explicitly. Try checking node.type() to see what type of node you're dealing with. It's easy to filter to only the elements.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜