2009-12-15 62 views
1

上周我问了一个类似的问题,但没有得到真正指出它的答案。我怀疑必须使这里更清楚地说明这个问题得好:PHP - 从一个更大的XML文档中提取一段XML

鉴于这种XML:

<?xml version="1.0" encoding="utf-8"?> 
<everyone> 
    <guest> 
    <name>Joseph Needham</name> 
    <age>53</age> 
    </guest> 
    <guest> 
    <name>Lu Gwei-djen</name> 
    <age>31</age> 
    </guest> 
</everyone> 

如何退还正是这样:

<guest> 
    <name>Joseph Needham</name> 
    <age>53</age> 
    </guest> 
    <guest> 
    <name>Lu Gwei-djen</name> 
    <age>31</age> 
    </guest> 

我不想要的SimpleXML对象,我不想转换任何东西,我不希望只是节点的值,我不希望有一个新的XML文档与其相应的头......只是XML的块。不能使用外部库...没有任何不符合标准的平均PHP安装。我如何从另一个中提取一个?

我最好的猜测是?使用DomDocument以某种方式获取节点名称和内容,然后使用foreach循环重新构建我想要的内容,并回显各种节点名称和值(包括行结尾)以正确格式化所有内容。但是,这看起来可能会非常笨重。我怀疑有一个更简单的方法来做到这一点,所以我想看看是否有人在这里在stackoverflow知道这是什么方式(或可以告诉我,有,事实上,并不是一个更简单的方法)。提前致谢。

+1

如果您对您输入的格式担保,你不只是要删除的前两行,并删除最后一行? – catchmeifyoutry 2009-12-15 16:21:37

+0

好点,thx! – Lothar 2009-12-15 19:48:58

回答

2
$string = <<<XML 
<?xml version="1.0" encoding="utf-8"?> 
<everyone> 
    <guest> 
    <name>Joseph Needham</name> 
    <age>53</age> 
    </guest> 
    <guest> 
    <name>Lu Gwei-djen</name> 
    <age>31</age> 
    </guest> 
</everyone> 

XML; 

$xml = new SimpleXMLElement($string); 
$nodes = $xml->xpath('/everyone/guest'); 

$result = ''; 
foreach ($nodes as $node) { 
    $result .= $node->asXML()."\n"; 
} 
echo $result; 
die; 
+0

这很容易做到,并且比其他解决方案更快或更快。我很感激帮助。 – Lothar 2009-12-15 19:42:31

1
preg_match('`<guest>.*</guest>`is', $xml, $matches); 
print_r($matches); 
2
使用的XMLReader的
$reader = new XMLReader(); 
$reader->xml($xml_str); 
$reader->read(); 
$inner = $reader->readInnerXML(); 

// $inner is your desired xml string. 

一个优点是,它使用比的SimpleXML或DOM类存储器更少。另一个是它非常快。

+0

我认为这将会是最快的,但是当我将其与其他解决方案进行比较时,结果证明它是最慢的。使用一个包含1000个节点的XML文件进行选择,其他解决方案的完成时间通常约为60%(即simplexmlelement xpath解决方案的平均值为5.8 ms,而这个基于XMLReader的解决方案的平均值为10 ms)也许我做错了什么。不过谢谢你的建议。帮助我更好地理解整件事情。 – Lothar 2009-12-15 19:48:05

+0

我刚刚在一个非常大的文件上测试了这个,你是对的;它比SimpleXML和DOMXPath慢,并且与您的测试显示的比例大致相同。这让我感到惊讶,因为我发现从大文件中逐个检索所有数据时速度通常更快。 – GZipp 2009-12-15 21:09:02

+0

它仍然使用较少的内存? – shredding 2014-02-13 11:46:53

2

类似这样的事情(使用XPath - 如果你有另一种方式来获取访客元素列表,你可以使用它)应该做的伎俩。

$xml = ''; 
$xpath = new DOMXPath($document); 
foreach($xpath->query('//everyone/guest') as $guestNode) { 
    $xml .= $document->saveXML($guestNode); 
} 
+0

这工作,但由于某种原因,我不断获得额外的空间添加到东西。我想可以用trim()把它删除。感谢您的建议。 – Lothar 2009-12-15 19:43:20