使用 XPath 获取 SVG 中的元素
Using XPath to get an element in SVG
我正在尝试使用 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" width="90" height="90" stroke-width="5" 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
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);
您可以使用 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" 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>
我正在尝试使用 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" width="90" height="90" stroke-width="5" 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
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);
您可以使用 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" 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>