使用 XPath 获取 SVG 中的元素

Posted

技术标签:

【中文标题】使用 XPath 获取 SVG 中的元素【英文标题】:Using XPath to get an element in SVG 【发布时间】:2022-01-20 21:21:04 【问题描述】:

我正在尝试使用 XPath 获取 SVG 文件中的元素。我尝试了以下代码,但 singleNodeValue 为空。 doc 似乎是正确的,所以我猜evaluate() 参数或 XPath 是错误的,但我找不到任何错误。为什么它不起作用?

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"   stroke- stroke="#f00" fill="#f00" fill-opacity="0.5" />
    </symbol>

</svg>

经过一些测试,我发现如果我删除xmlns="http://www.w3.org/2000/svg",它会起作用。我在网上搜索了一下,找到了答案:Why XPath does not work with xmlns attribute

【问题讨论】:

你能解释一下提取标签的目的是什么吗? @Dementic 当 SVG 包含多个图像时仅显示选定的图像。问题中的 SVG 仅用于说明;不是我尝试使用的真正的 SVG。 【参考方案1】:

您可以在 XPath 1 和 evaluate 函数中使用命名空间解析器,甚至可以在 XPath 2 及更高版本中使用 XPath 默认命名空间,例如 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"   stroke- stroke="#f00" fill="#f00" fill-opacity="0.5" />
    </symbol>
    <symbol dog:label="cat">
        <rect y="5" x="5"   stroke- 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);
&lt;script src="https://www.saxonica.com/saxon-js/documentation/SaxonJS/SaxonJS2.rt.js"&gt;&lt;/script&gt;

【讨论】:

【参考方案2】:

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

【讨论】:

你用的是CSS选择器吧?所以,我必须使用 CSS 选择器,而不是 Xpath? querySelector 是一个 javascript 选择器(具有特定值的标签和属性)。 developer.mozilla.org/en-US/docs/Web/API/Document/querySelector 既然你的文档已经解析好了,你可以使用任何JS方法来操作它。

以上是关于使用 XPath 获取 SVG 中的元素的主要内容,如果未能解决你的问题,请参考以下文章

Selenium WebDriver:使用 XPath 单击 SVG 中的元素

如何通过 Java 使用 XPath 和 Selenium WebDriver 单击 SVG 元素

如何在 Selenium WebDriver 中使用 xPath 来抓取 SVG 元素?

无法在 Kendo UI 图表上通过 xpath 定位 SVG 元素

无法在Kendo UI图表上通过xpath定位SVG元素

selenium玩转svg操作