XMLDoc调用evaluate执行XPath无结果,必须放入DOM才生效是正常逻辑吗?
问题1解答
这不属于正常设计逻辑。W3C标准中,XMLDocument实例自带的evaluate()方法默认作用于自身文档的上下文,不会主动关联当前页面的HTML document。你之前查询无结果的核心原因是TEI/XML文档带有默认命名空间,你编写的XPath没有指定命名空间匹配规则,无法命中带命名空间的目标节点,并非evaluate()遍历了错误的文档。
问题2解答
你目前的临时方案存在很多隐患:XML内容插入HTML节点时,HTML解析器会自动丢弃XML的命名空间信息,遇到和HTML原生标签重名的元素还会被错误解析,甚至存在执行XML内恶意脚本的安全风险,不推荐长期使用。
规范的最佳实践是直接在解析得到的XMLDocument实例上处理命名空间后执行XPath查询,示例代码如下:
// 1、获取并解析XML文档 const xmlStr = await fetch(t.source).then(res => res.text()) const xmlDoc = new DOMParser().parseFromString(xmlStr, "application/xml") // 2、定义命名空间解析器,映射TEI官方命名空间 const nsResolver = prefix => prefix === 'tei' ? 'http://www.tei-c.org/ns/1.0' : null // 3、XPath添加自定义前缀匹配命名空间,调用XMLDocument自身的evaluate查询 const xpathExp = "//tei:div[@type='poem'][8]" const queryResult = xmlDoc.evaluate( xpathExp, xmlDoc, nsResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ) // 4、序列化查询到的XML节点写入目标区域 if (queryResult.snapshotLength > 0) { const serializer = new XMLSerializer() textSample.innerHTML = serializer.serializeToString(queryResult.snapshotItem(0)) }
额外注意:XML节点本身没有innerHTML属性,需要用XMLSerializer将节点序列化为字符串后再写入HTML元素。
内容的提问来源于stack exchange,提问作者cubap
相关产品推荐
相关产品推荐

