2011-06-28 23 views
2

私はPHP 5.3+、特にsimplexml_load_string()を使用しています。私は幸運で数時間のソリューションを探してみましたので、どんな助けも大歓迎です。XPathを使用してXMLからタグ名を取得

特定のレベルでXMLファイルに存在するすべてのタグ名を識別する体系的な方法が必要です。

例XML:

<?xml version="1.0"?> 
<properties> 
    <property> 
    <ID>243</ID> 
    <area>5,000</area> 
    <bathrooms>5</bathrooms> 
    <bedrooms>4</bedrooms> 
    <images> 
     <image>http://urltoimage.com/image1.jpg</image> 
     <image>http://urltoimage.com/image2.jpg</image> 
    </image> 
    </property> 
    <property> 
    <ID>332</ID> 
    <garage>2</garage> 
    <bathrooms>2</bathrooms>  
    <images> 
     <image>http://urltoimage.com/image5.jpg</image> 
     <image>http://urltoimage.com/image1.jpg</image> 
    </image>  
    </property> 
<properties> 

私はの配列を取得できるようにする必要があります。

  • ID
  • エリア
  • バスルーム
  • 寝室
  • ガレージ

最初の 'property'要素には「ガレージ」がありません。したがって、XML全体のすべての子要素が集約されます。私は、 'property'要素の下に存在するすべてのタグ名を識別できる必要があり、理想的には子要素を持つ要素を除外する必要があります。子供がいる要素(この例では「画像」)が出てくるのを回避することはできますが、XPathにもその部分を処理させてもらえます。

異なるタグ変数を持つプロパティデータの複数のXMLフィードを集約しています。インポートする前に、そのデータを渡す前にXMLで使用されているすべての異なるタグ名のアイデアが必要ですプログラムの残りの部分に渡します。

したがって、構築できるXPathクエリはありますか?パフォーマンスが要因であり、私はPHP関数の最適な設定が何であるか分からないので、提案を探しています。

+0

どちらのソリューションは、働いていた - のおかげでみんなを。私は、どれが速いかを見るためにベンチマーキングを行いました。彼らは非常に近いです。小さなXMLファイルでは、Philの方法は高速でした(.008対0.010秒)。より大きなXMLファイルでは、それらは事実上同一でした。 – Andy

答えて

2

foreachループ内でこの

$doc = simplexml_load_string($xml); 
$nodes = $doc->xpath('//property/*[not(*)]'); 
$properties = array(); 
foreach ($nodes as $node) { 
    $properties[$node->getName()] = true; 
} 
$properties = array_keys($properties); 

のようなものを試してみてください、あなたは値が既に入力されていますが、私は上記がより速くなると考えましたかどうかを確認することができます。

1

プロパティの子を見つけるには、SimpleXMLElement::children()関数を使用します。

例:

<?php 

$string = <<<END 
<?xml version="1.0"?> 
<properties> 
    <property> 
    <ID>243</ID> 
    <area>5,000</area> 
    <bathrooms>5</bathrooms> 
    <bedrooms>4</bedrooms> 
    <images> 
     <image>http://urltoimage.com/image1.jpg</image> 
     <image>http://urltoimage.com/image2.jpg</image> 
    </images> 
    </property> 
    <property> 
    <ID>332</ID> 
    <garage>2</garage> 
    <bathrooms>2</bathrooms>  
    <images> 
     <image>http://urltoimage.com/image5.jpg</image> 
     <image>http://urltoimage.com/image1.jpg</image> 
    </images>  
    </property> 
</properties> 
END; 

// Load the XML using the SimpleXML class. 
$xml = simplexml_load_string($string); 

// Loop through all of the properties. 
foreach ($xml->property as $property) 
{ 
    // Reset the property tags array for this property. 
    $property_tags = array(); 

    foreach ($property->children() as $children) 
    { 
    // If a tag was found, add it to the array. 
    if (! empty($children[0])) 
     $property_tags[] = $children[0]->getName(); 
    } 

    // Output the list to the screen (this could be removed). 
    print_r($property_tags); 
} 

出力:

Array 
(
    [0] => ID 
    [1] => area 
    [2] => bathrooms 
    [3] => bedrooms 
    [4] => images 
) 
Array 
(
    [0] => ID 
    [1] => garage 
    [2] => bathrooms 
    [3] => images 
) 

するのではなく、単に、(XML文書に含まれるすべてのプロパティのために)利用可能なすべてのタグの一覧を取得したい場合これを行う:

// Loop through all of the properties. 
foreach ($xml->property as $property) 
{ 
    foreach ($property->children() as $children) 
    { 
    // If a tag was found, add it to the array if it's not already in it. 
    if (! empty($children[0]) && ! in_array($children[0]->getName(), $property_tags)) 
     $property_tags[] = $children[0]->getName(); 
    } 
} 

// Output the list to the screen (this could be removed). 
print_r($property_tags); 

出力:

Array 
(
    [0] => ID 
    [1] => area 
    [2] => bathrooms 
    [3] => bedrooms 
    [4] => images 
    [5] => garage 
) 
+0

あなたの答えはとても良かったですが、それは他の方法よりも遅いヘアラインでした。しかし、素晴らしい答えをありがとう。 – Andy

関連する問題