如何有效地从xml节点的父节点获取属性

时间:2017-04-12 14:08:36

标签: php xml xpath

我正在使用SimpleXML / XPath编写一个PHP脚本,该脚本需要打印XML文件的句子引用,该文件的结构类似于以下结构:

int

问题在于我需要返回包含带有attr =“desired_val”的单词的每个句子,然后返回包含其文本,书籍,章节和句子编号的引文。我目前正在使用xpath查询进行第一部分

int[]

和第二部分,其具有基于每个返回句子的ID属性的一系列后续xpath查询,例如,对于文本节点:

<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>

(依此类推,对于其他相关节点)。我的问题是,对于大量记录而言,这变得非常低效,并导致脚本超过大约十个结果。任何人都可以建议更好的方法吗?

1 个答案:

答案 0 :(得分:0)

如果您需要所有匹配,我能想象的唯一优化是减少大量查询。构建整个匹配列表需要花费很多时间,以便在文档中寻找每个匹配以收集剩余信息。相反,最好只需一步即可从您的文档中查询必要的数据。在数据库应用程序中也会出现同样的问题,人们执行的SQL语句太多而不是只在一个查询中执行所有操作。

SQL for XML称为XQuery。如果您使用XQuery而不是XPath,您只需一步即可收集所有必要的数据。以下示例已使用Saxon-HE作为XQuery引擎进行了测试。

<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>

Saxon-HE可以通过以下命令安装在Ubuntu上。

apt-get install libsaxonhe-java

我不知道哪种XQuery引擎最适合PHP。