2012-10-16 81 views
4

我用simplexml_load_file()函數解析xml文件。當我遇到兩個同名的節點時,我遇到了問題。我的XML文件的結構是:用PHP解析XML。重複節點名稱

<company> 
    <name>Test Co</name> 
    <link href="link1" rel="self"/> 
    <link href="link2" rel="www"/> 
</company> 

這裏是代碼:

$parametrs = simplexml_load_file("my.xml"); 
foreach ($parametrs->company as $param) { 
    echo $param->name;  
} 

我怎樣才能呼應鏈接2,從每家公司?

+0

我想得到link2 url。 – moonvader

+1

爲什麼你想要第二個鏈接?它真的是你想要的,還是你想要鏈接rel =「www」? –

回答

3
<?php 
$xml = '<?xml version="1.0" ?> 
<company> 
<name>Test Co</name> 
<link href="link1" rel="self"/> 
<link href="link2" rel="www"/> 
</company>'; 


$parameters = new SimpleXmlElement($xml); 

echo (string)$parameters->link[1]['href']; // note you must cast here! 

這將輸出 '鏈接2'(周圍沒有引號)。

此外,您可能需要做一些檢查前面,這些因素的存在,但我會離開,你作爲它的問題的範圍之外;)

+0

請注意,此解決方案取決於元素的順序。我建議你使用xPath-way來做到這一點! Specialy如果你不自己構建XML –

+0

謝謝。有用! – moonvader

+0

請注意,當您將XML文件加載到SimpleXML中時,返回的對象表示XML根節點,在這種情況下爲''。 –

0

您可以使用XPath:

<?php 
$sxml = simplexml_load_string('<company> 
<name>Test Co</name> 
<link href="link1" rel="self"/> 
<link href="link2" rel="www"/> 
</company>'); 


$link = $sxml->xPath('//link[@rel="www"]'); 

var_dump($link); 

http://codepad.viper-7.com/C4VU9q

問候

+1

在這種情況下,這是無用的,因爲你需要提前知道'link2'的值(哪個OP肯定不會)......如果你打算使用xpath,你想告訴它找到第二個'link'節點。 – quickshiftin

-1

你可以試試我的課它使用簡單的XML

這裏的代碼

<?php 
    class xml_grabber 
     { 
      private $xml_file  = '' ; 
      private $xml_link  = '' ; 
      private $xml_dom  = '' ; 
      private $xml_type  = '' ; 
      private $xml_content = '' ; 
      private $xml_errors  = array() ; 
      public $xml_stack  = 0 ; 
      public $only_text  = 0 ; 

      private $xml_connect_count = 0 ; 

      public function __construct($link_file_com = '') 
        { 
         if(!$link_file_com) 
          { 
           $this->xml_errors['construct'] = 'No Xml In Construct' ; 
           return false; 
          } 
         elseif(!function_exists('simplexml_load_file') || !function_exists('simplexml_load_string') || !function_exists('simplexml_import_dom')) 
          { 
           $this->xml_errors['functions'] = 'simple xml function not exists' ; 
           return false; 
          } 
         else 
          { 
          $this->set_xml(trim($link_file_com)) ; 
          } 
        } 

      public function only_text($val = 0) 
        { 
        $this->only_text = $val ; 
        } 

      public function set_xml($xml) 
        { 
         if(isset($xml{3})) 
         { 
          if(file_exists($xml)) 
           { 
           $this->xml_type = 1 ; 
           $this->xml_file = $xml ; 
           } 
          elseif(filter_var($xml, FILTER_VALIDATE_URL)) 
           { 
           $this->xml_type = 2 ; 
           $this->xml_link = $xml ; 
           } 
          else 
           { 
           $this->xml_type = 3 ; 
           $this->xml_dom = $xml ; 
           } 
         } 
         else 
         { 
          $this->xml_type = '' ; 
         } 
        } 

      public function get_xml() 
        { 
         if($this->xml_type == '') 
          { 
           return false ; 
          } 
         elseif($this->xml_type == 1) 
          { 
           return $this->xml_file ; 
          } 
         elseif($this->xml_type == 2) 
          { 
           return $this->xml_link ; 
          } 
         elseif($this->xml_type == 3) 
          { 
           return $this->xml_dom ; 
          } 
        } 

      public function set_columns($new_columns= array()) 
        { 
         return $this->xml_columns = $new_columns ; 
        } 
      public function get_columns() 
        { 
        return $this->xml_columns ; 
        } 

      public function load() 
        { 
        if($this->xml_type == '') 
          { 
           $this->xml_errors['loader'] = 'Unknown XML type' ; 
           return false; 
          } 
         elseif($this->xml_type == 1) 
          { 
           $xml = simplexml_load_file($this->xml_file,null, LIBXML_NOCDATA) ; 
           $this->xml_content = $xml ; 
          } 
         elseif($this->xml_type == 2) 
          { 
           $con = $this->connect($this->xml_link); 
           $this->xml_content = simplexml_load_string(trim($con),null, LIBXML_NOCDATA) ; 
          } 
         elseif($this->xml_type == 3) 
          { 
           return $this->xml_dom ; 
          } 
        } 

      public function fetch($return = 'array') 
        { 
         $xml = array() ; 
         if($this->xml_content) 
          { 
           print_r ($this->get_attribute($this->xml_content)) ; 
          } 
        } 

      public function get_attribute($object) 
        { 
         if((is_array($object) || is_object($object)) && count($object) > 0) 
          { 
            foreach($object as $k => $val) 
             { 
              $count = count($val) ; 

              $cou = count($object->$k) ; 

              if($count > 0 and is_array($val) || is_object($val)) 
               { 
               if($cou > 1) 
                { 
                 $result['item'][] = $this->get_attribute($val) ; 
                } 
               else 
                { 
                 $result[$k] = $this->get_attribute($val) ; 
                } 
               } 
              else 
               { 
               $attr = $val->attributes() ; 

               if(count($attr) > 0) 
                 { 
                 $var ; 
                 foreach($attr as $kk => $vv) 
                   { 
                   $var[$kk] = (string) $vv ; 
                   } 
                 if($cou > 1) 
                  { 
                   $result[$k][] = $var ; 
                  } 
                 else 
                  { 
                   $result[$k] = $var ; 
                  } 
                 } 
               else 
                 { 

                 $result[$k] = (string) $val ; 
                 } 
               } 
             } 
          } 
         else 
          { 
           $result[] = $object ; 
          } 

         return $result ; 
        } 

/* 
      public function fetch($return = 'array') 
        { 

         if($this->xml_content) 
          { 
           $rss_feed = $this->xml_content ; 
           $rss_title = (string) $rss_feed->channel->title ; 
           $rss_link = (string) $rss_feed->channel->link ; 
           $rss_cat = (string) $rss_feed->channel->category ; 
           $rss_image = (string) $rss_feed->channel->image->url ; 

           $rss_summary = 
              array 
              (
               'info' => 
                 array(
                   'title'=>$rss_title , 
                   'link'=>$rss_link , 
                   'cat'=>$rss_cat , 
                   'image'=>$rss_image 
                   ) , 
               'item' => array() 

              ) ; 

          if(is_array($rss_feed->channel) or is_object($rss_feed->channel)) 
           { 
             if(is_array($rss_feed->channel->item) or is_object($rss_feed->channel->item)) 
             { 
              foreach($rss_feed->channel->item as $item) 
                { 
                 if($item->enclosure && $item->enclosure->attributes()) 
                   { 
                    $image0 = $item->enclosure->attributes() ; 
                    $image_url = $image0 ['url'] ; 
                   } 

                 $result = array() ; 
                 foreach($item as $k=>$v) 
                   { 
                     $result[strtolower($k)] = strip_tags((string) $v) ; 
                   } 
                 if(isset($image_url{1})) 
                  { 
                   $result['image0'] = $image_url ; 
                  } 
                 $rss_summary['item'][] = $result ; 
                } 
             } 
             elseif(is_array($rss_feed->channel->entry) or is_object($rss_feed->channel->entry)) 
             { 
              foreach($rss_feed->channel->entry as $item) 
                { 
                 if($item->enclosure && $item->enclosure->attributes()) 
                   { 
                    $image0 = $item->enclosure->attributes() ; 
                    $image_url = $image0 ['url'] ; 
                   } 
                 $result = array() ; 
                 foreach($item as $k=>$v) 
                   { 
                     $result[strtolower($k)] = (string) $v ; 
                   } 
                 if(isset($image_url{1})) 
                  { 
                   $result['image0'] = $image_url ; 
                  } 
                 $rss_summary['item'][] = $result ; 
                } 
             } 
           } 
          else 
           { 
           if(is_array($rss_feed->item) or is_object($rss_feed->item)) 
             { 
              foreach($rss_feed->item as $item) 
                { 
                 if($item->enclosure && $item->enclosure->attributes()) 
                   { 
                    $image0 = $item->enclosure->attributes() ; 
                    $image_url = $image0 ['url'] ; 
                   } 
                 $result = array() ; 
                 foreach($item as $k=>$v) 
                   { 
                     $result[strtolower($k)] = (string) $v ; 
                   } 
                 if(isset($image_url{1})) 
                  { 
                   $result['image0'] = $image_url ; 
                  } 
                 $rss_summary['item'][] = $result ; 
                } 
             } 
             elseif(is_array($rss_feed->entry) or is_object($rss_feed->entry)) 
             { 
              foreach($rss_feed->entry as $item) 
                { 
                 if($item->enclosure && $item->enclosure->attributes()) 
                   { 
                    $image0 = $item->enclosure->attributes() ; 
                    $image_url = $image0 ['url'] ; 
                   } 
                 $result = array() ; 
                 foreach($item as $k=>$v) 
                   { 
                     $result[strtolower($k)] = (string) $v ; 
                   } 
                 if(isset($image_url{1})) 
                  { 
                   $result['image0'] = $image_url ; 
                  } 
                 $rss_summary['item'][] = $result ; 
                } 
             } 
           } 

           if($return == 'json') 
             { 
             return json_encode($rss_summary) ; 
             } 
           elseif($return == 'serialize') 
             { 
             return serialize($rss_summary) ; 
             } 
           elseif($return == 'xml') 
             { 
             return xml_encode($rss_summary) ; 
             } 
           else 
             { 
             return $rss_summary ; 
             } 

          } 
         else 
          { 
           $this->xml_errors['fetch'] = 'No Xml Content' ; 
          } 
        } 
*/ 

      protected function connect($link,$post='') 
        { 
         if(!filter_var($link, FILTER_VALIDATE_URL)) 
           { 
           $this->xml_errors['connect'] = 'Not Vaild Link To Get data' ; 
           return false ; 
           } 
         if(function_exists('curl_init')) 
          { 
          $cu = curl_init(); 
          curl_setopt($cu,CURLOPT_URL,$link); 
          curl_setopt($cu,CURLOPT_AUTOREFERER,true); 

          if($post != '') 
           { 
            curl_setopt($cu,CURLOPT_HEADER, 1); 
            curl_setopt($cu,CURLOPT_POST,3); 
            curl_setopt($cu,CURLOPT_POSTFIELDS,$post); 
           } 

           curl_setopt($cu,CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']); 
           curl_setopt($cu,CURLOPT_SSL_VERIFYPEER,false); 
           curl_setopt($cu,CURLOPT_SSL_VERIFYHOST,false); 
           curl_setopt($cu,CURLOPT_RETURNTRANSFER,true); 

          $co = curl_exec($cu) ; 
           if($co) 
            { 
             $con = $co ; 
            } 
           else 
            { 
             $this->xml_errors['connect'] = 'No Result From Curl' ; 
             $this->xml_errors['curl'] = curl_error($cu); 
            } 
           curl_close($cu) ; 
          } 

        if(!$con and function_exists('ini_get')) 
         { 

          $url_fopen = ini_get('allow_url_fopen') ; 

          if($url_fopen == 0) 
           { 
            if(function_exists('ini_set')) 
             { 
              ini_set('allow_url_fopen', 1) ; 
             } 
            $check_fopen = 1 ; 
           } 
          else 
           { 
            $check_fopen = 0 ; 
           } 

          if($check_fopen == 1) 
           { 
            $url_fopen = ini_get('allow_url_fopen') ; 
           } 

          if($url_fopen == 1) 
           { 

            if(function_exists('file_get_contents') and !$con) 
            { 
             $con = @file_get_contents($link) ; 
             if($con) 
              { 
               $con ; 
              } 
             else 
              { 
               $this->xml_errors['connect'] = 'No Result From file_get_contents' ; 
              } 
            } 

           elseif(function_exists('readfile') and !$con) 
            { 
             $con = @readfile($link); 
             if($con) 
              { 
               $con ; 
              } 
             else 
              { 
               $this->xml_errors['connect'] = 'No Result From readfile' ; 
              } 
            } 

           elseif(function_exists('file') and !$con) 
            { 
             $con = @file($link) ; 
             if($con) 
              { 
               $con ; 
              } 
             else 
              { 
               $this->xml_errors['connect'] = 'No Result From file' ; 
              } 
            } 

           } 
         } 

         if(!$con) 
          { 
          $this->xml_errors['connect'] = 'Curl And Allow Url Fopen Disabled On Server' ; 
          return false ; 
          } 
         elseif(stripos($con,'DDoS protection by CloudFlare') and $this->xml_connect_count < 1) 
          { 

           echo '<h2> Curl Answer No : '.$this->xml_connect_count.' </h2>'.$con.'<br />'; 
           preg_match('/'.preg_quote('.val(').'(.*?)'.preg_quote(');').'/is', $con, $match); 
       $matc = str_replace('+', " + ", $match[1]) ; 
       $matc = str_replace('*', " * ", $matc) ; 
       $post = eval ("return $matc ;") ; 
       $html=new DOMDocument(); 
       $html->loadHTML($con) ; 
       $xpath = new DOMXPath($html); 
       $tags = $xpath->query('//input[@type="hidden"]'); 
       $fields = array(); 
       foreach ($tags as $tag) { 
        $fields[trim($tag->getAttribute('name'))] = trim($tag->getAttribute('value')) ; 
       } 
       $post_data = 'act=jschl&jschl_vc='.$fields['jschl_vc'].'&jschl_answer='.$post ; 
       echo '<h2> I will post this info to curl </h2>'.$post_data.'<br /> ' ; 
       $this->xml_connect_count = $this->xml_connect_count + 1 ; 
       sleep(5) ; 
       $con = $this->connect($link , $post_data) ; 
       echo '<h2> Curl Answer No : 1 </h2>'. $con.'<br />' ; 
       preg_match('/^Set-Cookie: (.*?);/m', $con, $m); 
       echo '<h2> Cookie from Result </h2>' ;var_dump(parse_url($m[1])); 
          } 
         else 
          { 
          return $con ; 
          } 
        } 

      public function get_error() 
        { 
         return $this->xml_errors ; 
        } 

     } 

?> 

以下是如何使用它

<?php 
    $rss = new xml_grabber('xml.xml') ; 
     $rss -> load() ; 
    $x = $rss -> fetch() ; 

    print_r ($x) ; 
?> 

<?xml version="1.0" encoding="Windows-1256"?> 
    <rss version="2.0"> 
    <channel> 
      <info name="xml_reader" vesrion="1.0" author="sec.php"></info> 
      <title> Xml By sec.php </title> 
      <company> 
       <name>Test Co</name> 
       <link href="link1" rel="self"/> 
       <link href="link2" rel="www"/> 
      </company> 
      <company> 
       <name>Test Co</name> 
       <link href="link1" rel="self"/> 
       <link href="link2" rel="www"/> 
      </company> 
      <company> 
       <name>Test Co</name> 
       <link href="link1" rel="self"/> 
       <link href="link2" rel="www"/> 
      </company> 
    </channel> 
    </rss> 

結果 陣列 ( [頻道] =>數組 ( [信息] =>數組 ( [名稱] => xml_reader [vesrion] => 1.0 [作者] => sec.php )

 [title] => Xml By sec.php 
     [item] => Array 
      (
       [0] => Array 
        (
         [name] => Test Co 
         [link] => Array 
          (
           [0] => Array 
            (
             [href] => link1 
             [rel] => self 
            ) 

           [1] => Array 
            (
             [href] => link2 
             [rel] => www 
            ) 

          ) 

        ) 

       [1] => Array 
        (
         [name] => Test Co 
         [link] => Array 
          (
           [0] => Array 
            (
             [href] => link1 
             [rel] => self 
            ) 

           [1] => Array 
            (
             [href] => link2 
             [rel] => www 
            ) 

          ) 

        ) 

       [2] => Array 
        (
         [name] => Test Co 
         [link] => Array 
          (
           [0] => Array 
            (
             [href] => link1 
             [rel] => self 
            ) 

           [1] => Array 
            (
             [href] => link2 
             [rel] => www 
            ) 

          ) 

        ) 

      ) 

    ) 

+0

這看起來很複雜,因爲這個問題。你的班級究竟做了什麼? –

+0

我用它來閱讀網站或文件或dom的rss –

+0

它看起來不錯,但我認爲它不會真的幫助這裏。此外,這裏的XML只是XML,它不是RSS,也不與RSS有任何關係。 –

0

當您將XML文件加載到SimpleXML中時,返回的對象表示XML根節點,您的情況爲<company>

所以,你只需要得到第二個鏈接標籤,並得到它的href

$parametrs = simplexml_load_file("my.xml"); 
// you need to case here, as this is actually a SimpleXML element, not a string 
echo (string)$parametrs->link[1]['href']; 
+1

你真的應該習慣於在此處將字符串轉換爲(字符串)......在這種情況下,回聲會爲您做到這一點,但如果您不知道需要強制轉換,稍後您可以指定一個值而不是回聲,並想知道爲什麼它不是一個字符串。 – quickshiftin

+0

@quickshiftin:啊,是的,沒錯,SimpleXML實際上返回一個SimpleXMLElement,而不是一個字符串。我會添加演員。 –