使用 XPath 创建 XML 属性
Create XML attribute using XPath
我想创建一个 xml 属性,但为了找到我想要添加查询的元素,我需要使用 xpath。我该怎么做?
例子=
const xmlText = `<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title id="somethingeng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>`;
var doc = new DOMParser().parseFromString(xmlText,'text/xml');
var r = doc.evaluate("//*[@lang[contains(.,'eng')]]", doc, null, XPathResult.ANY_TYPE, null);
我想为这个 r 创建一个属性;
首先,xmlText
字符串应该是一个 template literals,现在它有新的行。
evaluate()
接缝很好,但结果是 XPathResult that needs to be iterated with XPathResult.iterateNext().
const xmlText = `<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title id="somethingeng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>`;
var doc = new DOMParser().parseFromString(xmlText,'text/xml');
var r = doc.evaluate("//*[@lang[contains(.,'eng')]]", doc, null, XPathResult.ANY_TYPE, null);
var next = r.iterateNext();
while (next) {
console.log(next.textContent);
next = r.iterateNext();
}
更新
基于迭代器,您需要收集您感兴趣的节点,然后再对其进行更改。在下文中,我创建了可以基于 XPath 表达式和表示新数据的对象创建子元素和属性的函数。
const xmlText = `<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title id="somethingeng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>`;
var doc = new DOMParser().parseFromString(xmlText, 'text/xml');
function addAttribute(doc, xpath, obj) {
let r = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
let nodes = [];
let next = r.iterateNext();
while (next) {
nodes.push(next);
next = r.iterateNext();
}
nodes.forEach(node => {
Object.keys(obj).forEach(key => {
let newattr = doc.createAttribute(key);
newattr.value = obj[key];
node.setAttributeNode(newattr);
});
});
}
function addChildNode(doc, xpath, obj) {
let r = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
let nodes = [];
let next = r.iterateNext();
while (next) {
console.log(next.textContent);
nodes.push(next);
next = r.iterateNext();
}
nodes.forEach(node => {
Object.keys(obj).forEach(key => {
let newnode = doc.createElement(key);
newnode.textContent = obj[key];
node.appendChild(newnode);
});
});
}
addAttribute(doc, "//title[@lang[contains(.,'eng')]]", {"data-lang":"eng", index: 2});
addChildNode(doc, "//book[number(price) < 30]", {sale: true});
console.log(doc.documentElement.outerHTML);
使用 XPathResult.snapshotItem() 找到解决方案。
var xmlText = `<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title id=\"somethingeng\">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>`;
var doc = new DOMParser().parseFromString(xmlText, 'text/xml');
var r = doc.evaluate("//*[@id[contains(.,'eng')]]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var index = 0;
while (index < r.snapshotLength) {
var next = r.snapshotItem(index);
next.setAttribute("value", "val");
index++;
}
var xmlSerializer = new XMLSerializer();
const updatedDoc = xmlSerializer.serializeToString(doc);
console.log(updatedDoc);
我想创建一个 xml 属性,但为了找到我想要添加查询的元素,我需要使用 xpath。我该怎么做?
例子=
const xmlText = `<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title id="somethingeng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>`;
var doc = new DOMParser().parseFromString(xmlText,'text/xml');
var r = doc.evaluate("//*[@lang[contains(.,'eng')]]", doc, null, XPathResult.ANY_TYPE, null);
我想为这个 r 创建一个属性;
首先,xmlText
字符串应该是一个 template literals,现在它有新的行。
evaluate()
接缝很好,但结果是 XPathResult that needs to be iterated with XPathResult.iterateNext().
const xmlText = `<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title id="somethingeng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>`;
var doc = new DOMParser().parseFromString(xmlText,'text/xml');
var r = doc.evaluate("//*[@lang[contains(.,'eng')]]", doc, null, XPathResult.ANY_TYPE, null);
var next = r.iterateNext();
while (next) {
console.log(next.textContent);
next = r.iterateNext();
}
更新
基于迭代器,您需要收集您感兴趣的节点,然后再对其进行更改。在下文中,我创建了可以基于 XPath 表达式和表示新数据的对象创建子元素和属性的函数。
const xmlText = `<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title id="somethingeng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>`;
var doc = new DOMParser().parseFromString(xmlText, 'text/xml');
function addAttribute(doc, xpath, obj) {
let r = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
let nodes = [];
let next = r.iterateNext();
while (next) {
nodes.push(next);
next = r.iterateNext();
}
nodes.forEach(node => {
Object.keys(obj).forEach(key => {
let newattr = doc.createAttribute(key);
newattr.value = obj[key];
node.setAttributeNode(newattr);
});
});
}
function addChildNode(doc, xpath, obj) {
let r = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
let nodes = [];
let next = r.iterateNext();
while (next) {
console.log(next.textContent);
nodes.push(next);
next = r.iterateNext();
}
nodes.forEach(node => {
Object.keys(obj).forEach(key => {
let newnode = doc.createElement(key);
newnode.textContent = obj[key];
node.appendChild(newnode);
});
});
}
addAttribute(doc, "//title[@lang[contains(.,'eng')]]", {"data-lang":"eng", index: 2});
addChildNode(doc, "//book[number(price) < 30]", {sale: true});
console.log(doc.documentElement.outerHTML);
使用 XPathResult.snapshotItem() 找到解决方案。
var xmlText = `<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title id=\"somethingeng\">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>`;
var doc = new DOMParser().parseFromString(xmlText, 'text/xml');
var r = doc.evaluate("//*[@id[contains(.,'eng')]]", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var index = 0;
while (index < r.snapshotLength) {
var next = r.snapshotItem(index);
next.setAttribute("value", "val");
index++;
}
var xmlSerializer = new XMLSerializer();
const updatedDoc = xmlSerializer.serializeToString(doc);
console.log(updatedDoc);