javascript - 利用内置的 XPath 引擎来查询 javaScript 对象

标签 javascript xml xpath

注意:我并不是在寻找查询 HTML 文档本身的方法。我想从 javaScript 对象创建自己的文档,并将其作为根参数传递给 evaluate 函数。

假设我有以下脚本:

function Attribute(name, value) {
    this.name;
    this.value;
}

function Node(nodeName) {
    this.nodeName = nodeName;
    this.textContent = "";
    this.childrenNodes = [];
    this.attributes = [];
}

var root = new Node("root");
root.attributes.push(new Attribute("name", "treeRoot"));

var c1 = new Node("child");
c1.attributes.push(new Attribute("name", "child1"));
c1.textContent = "I'm the first child!";

var c2 = new Node("child");
c2.attributes.push(new Attribute("name", "child2"));

root.childrenNodes.push(c1);
root.childrenNodes.push(c2);

这代表以下简单的 XML:

<root name="treeRoot">
    <child name="child1">
        I'm the first child!
    </child>
    <child name="child2"/>
</root>

我想使用内置的 XPath 引擎来查询这个类似 XML 的结构。类似于:

myDocument = createDocument(root);
myDocument.evaluate("/root/child[@name='child2']", myDocument, null, XPathResult.ANY_TYPE, null);

这将返回包含 c1 NodeNode 集合的 XPathResult

如何实现createDocument函数?

编辑:

我的目标是能够查询 javaScript 对象。在 Java 中,我可以创建一个 Document 对象并使用 XPath 来查询它。我正在寻找 javaScript 中类似的东西。

最佳答案

这里需要几个函数来将“DOM”实现转换为标准 XML DOM - 一个用于创建文档,另一个用于递归创建元素:

// create a document based on a Node instance
function toXmlDom(node) {
    // create a document
    var doc = document.implementation.createDocument('', '');

    // convert the root node
    var e = toXmlElement(doc, node);

    // add root to document
    doc.appendChild(e);
    return doc;
}

// convert a Node and its children to an XML element
function toXmlElement(doc, node) {
    // create an element
    var e = doc.createElement(node.nodeName);

    // set its attributes
    for(var i = 0; i < node.attributes.length; i++) {
        var attr = node.attributes[i];
        e.setAttribute(attr.name, attr.value);
    }

    // set its text content
    e.textContent = node.textContent;

    // convert and add its child nodes
    for(var i = 0; i < node.childrenNodes.length; i++) {
        var childrenNode = node.childrenNodes[i];
        var childNode = toXmlElement(doc, childrenNode);
        e.appendChild(childNode);
    }

    return e;
}

// do the conversion
var myDocument = toXmlDom(root);

工作示例

console.clear();

function Attribute(name, value) {
    this.name = name;
    this.value = value;
}

function Node(nodeName) {
    this.nodeName = nodeName;
    this.textContent = "";
    this.childrenNodes = [];
    this.attributes = [];
}

function toXmlDom(node) {
    // create a document
    var doc = document.implementation.createDocument('', '');

    // convert the root node
    var e = toXmlElement(doc, node);

    // add root to document
    doc.appendChild(e);
    return doc;
}

function toXmlElement(doc, node) {
    // create an element
    var e = doc.createElement(node.nodeName);

    // set its attributes
    for(var i = 0; i < node.attributes.length; i++) {
        var attr = node.attributes[i];
        e.setAttribute(attr.name, attr.value);
    }

    // set its text content
    e.textContent = node.textContent;
    
    // convert and add its child nodes
    for(var i = 0; i < node.childrenNodes.length; i++) {
        var childrenNode = node.childrenNodes[i];
        var childNode = toXmlElement(doc, childrenNode);
        e.appendChild(childNode);
    }

    return e;
}

var root = new Node("root");
root.attributes.push(new Attribute("name", "treeRoot"));

var c1 = new Node("child");
c1.attributes.push(new Attribute("name", "child1"));
c1.textContent = "I'm the first child!";

var c2 = new Node("child");
c2.attributes.push(new Attribute("name", "child2"));

root.childrenNodes.push(c1);
root.childrenNodes.push(c2);

var myDocument = toXmlDom(root);

// get the text of the first child - "I'm the first child!"

var result = myDocument.evaluate("/root/child[@name='child1']", myDocument, null, XPathResult.ANY_TYPE, null);

var thisNode = result.iterateNext();
while (thisNode) {
    document.getElementById('result').innerHTML += thisNode.textContent + "<br/>";
    thisNode = result.iterateNext();
}

document.getElementById('doctext').value = myDocument.documentElement.outerHTML;
<p><b>/root/child[@name='child1'].textContent:</b> <span id="result"></span></p>

<b>Document XML</b><br/>
<textarea id="doctext" cols="50" rows="10"></textarea>

关于javascript - 利用内置的 XPath 引擎来查询 javaScript 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27940143/

相关文章:

xpath - 在 cucumber 测试中检查链接的正确方法是什么?

xml - 具有多个谓词的 xpath 未给出正确的值

java - 使用 XPath 解析 xml 文档。为什么要在结果中添加 <xml tag as a header>?

javascript - Angular:Swiper 轮播不工作 - 错误:node_modules/swiper/angular/angular/src/swiper-events.d.ts

javascript - 清除页面中的控件值而不从服务器 ASP.NET 回发

javascript - 解析angular2中的xml以在 View 中呈现

java - 使用简单的 xml 序列化程序 (v2.6.6) 文档没有根元素异常

javascript - 如何使用 :first-of-type rule inside a styled-components/emotion partial?

javascript - select 中的 ng-model 未定义

python - 在 python 中添加新的 XML 节点并漂亮地打印 XML