2016-09-29 188 views
2

我目前正在做這個建立一個名爲$tables的數組,但想知道是否有更簡單的方法來做到這一點?XPath一次選擇多個元素?

$tables = array(); 
$abbr = $states_xml->xpath('//StateAbbr'); 
$names = $states_xml->xpath('//StateName'); 

// State Abbreviations... 
while(list($key,$table) = each($abbr)) { 
    $tables[$key]['Abbr'] = (string) trim($table); 
} 

// State Names... 
while(list($key,$name) = each($names)) { 
    $tables[$key]['Name'] = (string) trim($name); 
} 

是否有可能調用1個去StateAbbrStateName元件並具有它們在陣列中輸出在相同的格式$tables是?

<diffgr:diffgram 
    xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" 
    xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"> 
    <NewDataSet 
     xmlns=""> 
     <Table diffgr:id="Table1" msdata:rowOrder="0"> 
      <StateAbbr>AL </StateAbbr> 
      <StateName>Alabama</StateName> 
     </Table> 
     <Table diffgr:id="Table2" msdata:rowOrder="1"> 
      <StateAbbr>AK </StateAbbr> 
      <StateName>Alaska</StateName> 
     </Table> 
     <Table diffgr:id="Table3" msdata:rowOrder="2"> 
      <StateAbbr>AS </StateAbbr> 
      <StateName>American Samoa</StateName> 
     </Table> 
     <Table diffgr:id="Table4" msdata:rowOrder="3"> 
      <StateAbbr>AP </StateAbbr> 
      <StateName>AP</StateName> 
     </Table> 
     ... 
    </NewDataSet> 
</diffgr:diffgram> 

我使用$states_xml = simplexml_load_string(THE STRING ABOVE);將XML加載到$states_xml

因此,表數組將是這個樣子:

array(57) { 
    [0]=> 
    array(2) { 
    ["Abbr"]=> 
    string(2) "AL" 
    ["Name"]=> 
    string(7) "Alabama" 
    } 
    [1]=> 
    array(2) { 
    ["Abbr"]=> 
    string(2) "AK" 
    ["Name"]=> 
    string(6) "Alaska" 
    } 
    [2]=> 
    array(2) { 
    ["Abbr"]=> 
    string(2) "AS" 
    ["Name"]=> 
    string(14) "American Samoa" 
    } 
... and so on... 

基本上,$states_xml看起來是這樣的。

無論如何要抓取所有的StateAbbrStateName這裏要輸出的所有Table元素,一氣呵成?似乎對我可能,但不知道如何處理這個比我目前正在做的方式。

回答

0

請儘量將使用array_merge_recursive

$abbr = $states_xml->xpath('//StateAbbr'); 
$names = $states_xml->xpath('//StateName'); 
$tables = array_merge_recursive($abbr, $names); 

顯示:

print_r($tables); 
0

是,這種單一的XPath,

//*[self::StateAbbr or self::StateName] 

將返回所有StateAbbrStateName元素的XML文檔中。

+0

不,這不起作用。我更新了輸出xml字符串的問題。 –

+0

嗯,它確實按照它的設計要做:使用單個XPath選擇所有'StateAbbr'和'StateName'元素。如果你真的想保留'StateAbbr'和'StateName'元素之間的關聯,那你爲什麼不選擇所有的表?例如:'// Table' – kjhughes

+0

因爲//表格返回的信息太多,無法輕鬆解析。在任何情況下,我決定拋棄'xpath'方法,只是簡單地執行一個'$ states = json_decode(json_encode($ states_xml),true);'然後再簡單地調用'$ states ['' NewDataSet'] ['Table']',它給了我我需要的東西。感謝您的幫助。 :) –

0

你應該迭代它們的父元素節點。該表達式是相對的SimpleXMLElement表示節點,但那不是你的情況需要:

$diffgram = new SimpleXMLElement($xml); 

$result = []; 
foreach($diffgram->xpath('.//Table') as $table) { 
    $result[] = [ 
    'Abbr' => trim($table->StateAbbr), 
    'Name' => trim($table->StateName) 
    ]; 
} 

var_dump($result); 

輸出:

array(4) { 
    [0]=> 
    array(2) { 
    ["Abbr"]=> 
    string(2) "AL" 
    ["Name"]=> 
    string(7) "Alabama" 
    } 
    [1]=> 
    array(2) { 
    ["Abbr"]=> 
    string(2) "AK" 
    ["Name"]=> 
    string(6) "Alaska" 
    } 
    [2]=> 
    array(2) { 
    ["Abbr"]=> 
    string(2) "AS" 
    ["Name"]=> 
    string(14) "American Samoa" 
    } 
    [3]=> 
    array(2) { 
    ["Abbr"]=> 
    string(2) "AP" 
    ["Name"]=> 
    string(2) "AP" 
    } 
} 

在DOM它看起來幾乎相同,但在這裏,你需要的XPath表達式瞭解詳情。

$document = new DOMDocument(); 
$document->loadXml($xml); 
$xpath = new DOMXpath($document); 

$result = []; 
foreach($xpath->evaluate('.//Table') as $table) { 
    $result[] = [ 
    'Abbr' => $xpath->evaluate('normalize-space(StateAbbr)', $table), 
    'Name' => $xpath->evaluate('normalize-space(StateName)', $table) 
    ]; 
} 

var_dump($result);