Quiero crear un atributo xml, pero para encontrar el elemento al que quiero agregar la consulta, necesito usar xpath. ¿Cómo puedo hacer esto?
Ejemplo =
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);Quiero crear un atributo para este r;
En primer lugar, la cadena xmlText debe ser una plantilla de literales ahora que tiene nuevas líneas.
evaluate() funcionó bien, pero el resultado es un XPathResult que debe repetirse con 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(); }Según el iterador, debe recopilar los nodos que le interesan y luego modificarlos. A continuación, creé funciones que pueden crear elementos secundarios y atributos basados en una expresión XPath y un objeto que representa los nuevos datos.
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);Encontré la solución usando 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);