Estoy tratando de obtener un elemento en un archivo SVG usando XPath. Probé el siguiente código, pero singleNodeValue es nulo. El doc parece ser correcto, por lo que supongo que los argumentos de evaluate() o XPath son incorrectos, pero no puedo encontrar nada incorrecto. ¿Por qué no funciona?
JavaScript
fetch('test.svg') .then(response => response.text()) .then(data=>{ const parser = new DOMParser(); const doc = parser.parseFromString(data, "text/xml"); console.log(doc); const res = doc.evaluate("//symbol[@label='square']", doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); console.log(res.singleNodeValue); })SVG
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <symbol label ="square"> <rect y="5" x="5" width="90" height="90" stroke-width="5" stroke="#f00" fill="#f00" fill-opacity="0.5" /> </symbol> </svg> Después de algunas pruebas, descubrí que funciona si xmlns="http://www.w3.org/2000/svg" . Busqué en la web y encontré una respuesta:¿Por qué XPath no funciona con el atributo xmlns?
var data = '<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><symbol label ="square"><rect y="5" x="5" width="90" height="90" stroke-width="5" stroke="#f00" fill="#f00" fill-opacity="0.5" /></symbol></svg>'; const parser = new DOMParser(); const doc = parser.parseFromString(data, "text/xml"); const res = doc.querySelector("symbol[label=square]"); console.log(res);Puede hacer uso de una resolución de espacio de nombres en XPath 1 y con la función de evaluate e incluso de un espacio de nombres predeterminado de XPath en XPath 2 y posteriores, como el que admite Saxon-JS 2:
const svgString = `<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:dog = "http://dog.com/dog"> <symbol dog:label="square"> <rect y="5" x="5" width="90" height="90" stroke-width="5" stroke="#f00" fill="#f00" fill-opacity="0.5" /> </symbol> <symbol dog:label="cat"> <rect y="5" x="5" width="90" height="90" stroke-width="5" stroke="#f00" fill="#f00" fill-opacity="0.5" /> </symbol> </svg>`; const doc = new DOMParser().parseFromString(svgString, 'application/xml'); const result = doc.evaluate(`//svg:symbol[@dog:label='cat']`, doc, function(prefix) { if (prefix === 'svg') return 'http://www.w3.org/2000/svg'; else if (prefix === 'dog') return 'http://dog.com/dog'; else return null; }, XPathResult.FIRST_ORDERED_NODE_TYPE, null); console.log(result.singleNodeValue); const result2 = SaxonJS.XPath.evaluate(`//symbol[@dog:label = 'cat']`, doc, { xpathDefaultNamespace : 'http://www.w3.org/2000/svg', namespaceContext : { 'dog' : 'http://dog.com/dog' } }); console.log(result2); <script src="https://www.saxonica.com/saxon-js/documentation/SaxonJS/SaxonJS2.rt.js"></script>