我只能用XPath從我的DOM中獲得結果節點,感覺不正確。
設定:
我正試圖在我的HTML頁面上顯示一個XML檔案(TEI/XML)的片段。我有一個XML檔案的URL和一個片段的XPath選擇器。我想我可以fetch()該檔案,并提取我想要的片段,就像這樣:
//real values, for one case,
//t.source = "https://centerfordigitalhumanities.github.io/Dunbar-books/The-Complete-Poems-TEI.xml"
// t.selector.value = "//div[@type='poem'][8]"
const sampleSource = await fetch(t.source)
.then(res => res.text()
.then(docStr => (new DOMParser()>。) parseFromString(docStr, "application/xml"/span>)
const poemText = sampleSource.evaluation(t.selector? value, sampleSource, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
textSample.innerHTML = poemText.snapshotItem(0).innerHTML。
沒有結果
嘗試了幾種不同的方法(改變contextNode,使用XPathSelector.evaluate()而不是XMLDoc.evaluate(),以及改變XPathResult),結果始終是空。
在沮喪中,我嘗試了更簡單的選擇器,并發現evaluate()只遍歷了我當前的HTML document,盡管沒有對它進行參考。
解決方法
將XML檔案轉儲到頁面的一個隱藏元素中是 "可行的"。const sampleSource = await fetch(t.source)
.then(res => res.text()
.then(docStr => hiddenElem.innerHTML = docStr)
const poemText = document.evaluation(t.selector? value, hiddenElem, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
textSample.innerHTML = poemText.snapshotItem(0).innerHTML。
問題
evaluate()只遍歷document,這就是它應該作業的方式嗎?- 是否有比我的解決方法更好的做法?
uj5u.com熱心網友回復:
好吧,這是一個TEI檔案,所以它的元素在命名空間http://www.tei-c.org/ns/1.0,不要指望對一個XML DOM檔案使用XPath 1和像div這樣的選擇器來選擇任何命名空間中的元素,它正好選擇沒有命名空間的div元素。要用XPath 1.0選擇命名空間中的元素,你需要使用evaluate的第三個引數,并將你可以選擇的前綴(如tei)與該命名空間系結,并使用例如//tei:div[@type='poem'][8]:
< script type=module>/span>
const sampleSource = await fetch('https://centerfordigitalhumanities.github.io/Dunbar-books/The-Complete-Poems-TEI.xml'/span>)
.then(res => res.text()
.then(docStr => (new DOMParser()>。) parseFromString(docStr, "application/xml") )。
const poemText = sampleSource. evaluate(`//tei:div[@type='poem'][8]`, sampleSource, prefix =>/span> prefix =='tei' ? 'http://www.tei-c.org/ns/1.0' : null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)。)
console.log(poemText.snapshotItem(0).textContent) 。
</script>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
使用XPath 2或3,例如Saxon-JS 2支持,你可以系結一個默認的元素命名空間,并使用未限定的命名如div來選擇該命名空間的元素。
<script src=https://www. saxonica.com/saxon-js/documentation/SaxonJS/SaxonJS2.rt.js></script>/span>
<script type=module>/span>
const sampleSource = await SaxonJS.getResource({ location : 'https://centerfordigitalhumanities.github.io/Dunbar-books/The-Complete-Poems-TEI.xml', type : 'xml' })。)
const poemText = SaxonJS.XPath。 evaluate(`//div[@type='poem'][8]`, sampleSource, { xpathDefaultNamespace : 'http://www.tei-c.org/ns/1.0'/span> })。
console.log(poemText.textContent)。
</script>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" class="snippet-box-edit snippet-box-result" frameborder="0"></iframe>
在XPath 1.0中沒有辦法,除非DOM環境允許你建立一個無命名空間的DOM(就像Java的非命名空間感知DocumentBuilder)。但據我所知,在瀏覽器中,情況并非如此。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/324043.html
標籤:
