简体   繁体   English

使用 XPath 创建 XML 属性

[英]Create XML attribute using XPath

I want to create an xml attribute but in order to find the element I want to add the query on, I need to use xpath.我想创建一个 xml 属性,但为了找到要添加查询的元素,我需要使用 xpath。 How can I do this?我怎样才能做到这一点?

Example =示例 =

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);

I want to create an attribute for this r;我想为这个 r 创建一个属性;

First of all the xmlText string should be a template literals now that is has new lines.首先xmlText字符串现在应该是一个模板文字,它有新的行。

evaluate() seamed fine, but the result of that is a XPathResult that needs to be iterated with XPathResult.iterateNext() . evaluate()接缝很好,但结果是需要使用XPathResult.iterateNext ()迭代的 XPathResult。

 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(); }

Update更新

Based on the iterator you need to collect the nodes that you are interested in and then alter them afterwards.根据迭代器,您需要收集您感兴趣的节点,然后再更改它们。 In the following I created functions that can create child elements and attributes based on a XPath expression and an object representing the new data.在下文中,我创建了可以基于 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);

Found the solution by using XPathResult.snapshotItem() .通过使用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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM