2017-04-12 43 views
2

我正在使用SimpleXML/XPath的需要打印引文從XML文件的句子PHP腳本屬性,它具有類似的結構如下:如何從一個XML節點的父母有效

<text name="text_title"> 
    <book name="book_title"> 
    <chapter name="chapter_title"> 
     <sentence name="sentence_number" id="0000"> 
     <word attr="desired_val" id="1111" /> 
     <word attr="undesired_val" id="2222" /> 
     </sentence> 
    </chapter> 
    </book> 
</text> 

問題是我需要返回每個包含attr =「desired_val」的單詞的句子,然後返回包含其文本,書籍,章節和句子編號的引文。我目前做的第一部分與XPath查詢

//word[@$attr='desired_val']/ancestor::sentence 

和第二部分的一系列基於每個ID屬性隨後XPath查詢返回的句子,例如對於文本節點:

/text/[book/chapter/sentence[@id={$id}]]/@name 

(依此類推,用於其他相關節點)。我的問題是,這對大量記錄來說效率非常低,並且導致腳本超過大約十個以上的結果。任何人都可以提出一個更好的方法來做到這一點?

+0

你能分享所需的輸出嗎?你想如何簡化你的表情?你想擺脫「書/章/句子」還是什麼? – Andersson

+0

我想每個文字匹配的字數是相當大的。這導致文本元素的冗餘結果。你真的對多餘的結果列表感興趣嗎?如果不是,則在該文本元素中的第一個詞匹配之後停止在文本元素中的搜索就足夠了。 – ceving

+0

'/ text/[book/chapter/sentence [word [@id = {$ id}]]]/@ name' – splash58

回答

0

如果你需要所有的匹配,我能想象的唯一優化就是減少大量的查詢。花費很多時間來構建整個匹配列表,以便爲文檔中的每個匹配搜索剩餘的信息。相反,只需一步就可以從您的文檔中查詢必要的數據。在數據庫應用程序中也會出現同樣的問題,即人們執行太多SQL語句,而不是僅僅在一個查詢中執行所有操作。

用於XML的SQL稱爲XQuery。如果您使用XQuery而不是XPath,則只需一步即可收集所有必要的數據。以下示例已作爲XQuery引擎使用Saxon-HE進行過測試。

<results> 
{ 
    for $x in doc("text.xml")/text/book/chapter/sentence/word 
    where $x/@attr = "desired_val" 
    return <match text="{$x/../../../../@name}" 
       book="{$x/../../../@name}" 
       chapter="{$x/../../@name}" 
       sentence="{$x/../@name}" /> 
} 
</results> 

以下命令

java -cp /usr/share/java/Saxon-HE.jar net.sf.saxon.Query '!indent=yes' text.xquery 

提取從文檔中僅有一個步驟所需的信息。

<?xml version="1.0" encoding="UTF-8"?> 
<results> 
    <match chapter="chapter_title" 
      text="text_title" 
      book="book_title" 
      sentence="sentence_number"/> 
</results> 

撒克遜-HE可以在Ubuntu由如下指令安裝。

apt-get install libsaxonhe-java 

我不知道哪個XQuery引擎最適合PHP。

+0

非常感謝這個提示 - 昨晚我對一個朋友說「我需要的是XML for SQL」,所以這看起來很有希望。我會研究它並報告任何結果。對於PHP,這些看起來是鎮上的主要遊戲: [zorba](http://www.zorba.io/home), [BaseX](http://docs.basex.org/wiki/ Main_Page), [Xquery Lite](http://phpxmlclasses.sourceforge.net/show_doc.php?class=class_xquery_lite.html) –

+0

通過安裝和使用,我能夠完全按照需要(並且非常快速) [BaseX](http://basex.org/)處於服務器模式。以前服務器謀殺查詢的替代方法在338ms左右返回。真的很感謝幫助,@ceving和大家。 –

相關問題