2009-12-15 58 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