当混合内容时检索XML子节点

时间:2012-06-28 19:00:06

标签: php simplexml

我在这里读过几个似乎与我所遇到的问题有关(直接或间接)的问题,但到目前为止我都没有满足我的具体需要,所以我想我会解释我的情况,看看我们是否可以一起得出答案。

我有一个XML类别数据库(特别是AIML),我想使用simpleXML函数进行解析,以得到合适的输出。此解析的输出将从所选类别中的标记处理。一个简单的示例类别如下所示:

<category>  
  <pattern>HOW ARE YOU</pattern>  
  <template>I am fine, how are you?</template> 
</category>

&lt; template&gt;上面显示的标记可以包含任何文本,如上所示,或者任意数量的不同AIML标记中的一个或多个,可以单独使用,也可以穿插文本。可能性几乎无穷无尽。这是一个更复杂的例子:

<category>
  <pattern>NESTED RANDOM TEST</pattern>
  <template>
    <random>
      <li>
        <random>
          <li>Choice #1-1</li>
          <li>Choice #1-2</li>
          <li>Choice #1-3</li>
        </random>
      </li>
      <li>
        This is some example text, along with another RANDOM tag:
        <random>
          <li>Choice #2-1</li>
          <li>Choice #2-2</li>
          <li>Choice #2-3</li>
        </random>
      </li>
      <li>
        <random>
          <li>Choice #3-1</li>
          <li>Choice #3-2</li>
          <li>Choice #3-3</li>
        </random>
        This is some text that appears [i]after[/i] a RANDOM tag.
      </li>
    </random>
  </template>
</category>

如果模板标签只包含文本,或者它只包含其他AIML标签,我解析它的内容没有问题,但如果它有文本和标签的组合,就像在第二和第三外部&lt; li&gt; ;上面例子中的部分,如果首先有文本,我会丢失标签,如果有一个标签,则丢失文本。无论文本在标签内发生“深”还是“浅”,都会出现此问题。因此,我在这里遇到了一些问题。

正如我已经提到过的,我已经阅读了几个这种性质的问题,到目前为止我还没有找到满意的答案。但是,我怀疑这可能是因为我不完全理解所涉及的一些概念,因此可能无法正确实施某些解决方案。例如,this post提到使用xslt“预处理”xml,并且似乎就像处理我的问题一样,但我完全不知道如何实现它。另外,我没有使用xStream,所以我甚至不知道这是否是可以实现的。我担心我从未接受过正式的PHP培训,所以我的经验有点不稳定。 :)

我希望我已经提供了足够的信息来清楚我的情况,而不是太“罗嗦”。

2 个答案:

答案 0 :(得分:1)

虽然提出的答案确实很聪明,但我发现自己完全放弃了SimpleXML,而是使用了PHP的内置DOMElement Class。它支持暴露裸文本内容的类和方法,因为它是自己的谨慎节点。

答案 1 :(得分:0)

虽然这可能不是最好解决我的问题的方法,但我发现了一个相当简单的(对我来说,至少)有点优雅的方式来处理我的问题,使用preg_replace()将任何纯文本实例括在&lt; text&gt;中的XML字符串中标签。这就是我想出的:

//First, some simple mixed-content XML:
$myTemplate = '<template>Hello, <get name="name" />. I\'m glad to meet you.</template>';
$myTemplate = preg_replace('~>(.*?)<~', '><text>$1</text><', $myTemplate);
/*
This can add unnecessary, empty <text> tags under certain circumstances, so the next line
removes empty tag sets
*/
$myTemplate = str_replace('<text></text>', '', $myTemplate);
/*
This makes the template look like this:

<template><text>Hello, </text><get name="name" /><text>. I\'m glad to meet you.</text></template>

Now, to load my template as XML.
*/
$xml = new SimpleXMLElement($myTemplate);

从那里,我可以根据需要解析XML。正如我所说,这可能不是最好的方法,但它是有效的,只添加几行代码。我仍然喜欢听到其他处理方法,但就目前而言,这样做。我希望这有助于其他人。 :)