Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: XML => PHP => MySQL
 
 автор: elenaki   (25.09.2006 в 13:30)   письмо автору
 
 

ребята! помогите разобрать XML. прочитала кучу тем, но не нашла того, что нужно. а нужно вот что:
прочитать *.xml, составить запрос и закинуть в базу. у меня получается только прочитать и вывести
на экран. а когда начинаю формировать запрос, ничего не получается. использовала скрипт из
вашей гостевой (где xml парсится просто по тэгам)


<?
  
function StripXmlTags($Str)
  {
    
$Str=ereg_replace('<[/a-z]+>'''$Str);
    
$Str=trim($Str);
    return(
$Str);
  }

  
$XmlArr file("QUEST_XML1.XML");
  
$inx 0;
   
  for(
$i 0$i count($XmlArr); $i++)
  { 
$query "";
  
    if(
strpos($XmlArr[$i], '<id') !== false)
      
$query 'INSERT INTO pricelist values ("'.StripXmlTags($XmlArr[$i]).'", ';
    if(
strpos($XmlArr[$i], '<price') !== false)
      
$query .= '"'.StripXmlTags($XmlArr[$i]).'", ';
    if(
strpos($XmlArr[$i], '<offer') !== false)
      
$query .= '"'.StripXmlTags($XmlArr[$i]).'", ';
    if(
strpos($XmlArr[$i], '<availab') !== false)
      
$query .= '"'.StripXmlTags($XmlArr[$i]).'", '
    if(
strpos($XmlArr[$i], '<famcat') !== false)
      
$query .= '"'.StripXmlTags($XmlArr[$i]).'", '
    if(
strpos($XmlArr[$i], '<subcat') !== false)
      
$query .= '"'.StripXmlTags($XmlArr[$i]).'", ';   
    if(
strpos($XmlArr[$i], '<manuf') !== false)
      
$query .= '"'.StripXmlTags($XmlArr[$i]).'", ';   
    if(
strpos($XmlArr[$i], '<markaf') !== false)
      
$query .= '"'.StripXmlTags($XmlArr[$i]).'", '
    if(
strpos($XmlArr[$i], '<descr') !== false)
      
$query .= '"'.StripXmlTags($XmlArr[$i]).'", ';         
    if(
strpos($XmlArr[$i], '<retprice') !== false)
      
$query .= '"'.StripXmlTags($XmlArr[$i]).'", ';    
     if(
strpos($XmlArr[$i], '<kerdos') !== false)
      
$query .= '"'.StripXmlTags($XmlArr[$i]).'", ';      
     if(
strpos($XmlArr[$i], '<eshop') !== false)
      
$query .= '"'.StripXmlTags($XmlArr[$i]).'", ';
      if(
strpos($XmlArr[$i], '<apopou') !== false)
      
$query .= '"'.StripXmlTags($XmlArr[$i]).'")';          
   
      
$inx++;
     echo 
$query;
        
  }
 
?>




и вот этот.

<?
$p 
xml_parser_create(); 
xml_parse_into_struct($p,$simple,$vals,$index); 
xml_parser_free($p); 
//echo "Index array\n"; 
//print_r($index); 
echo "<br>Vals array<br><pre>"
print_r($vals);
echo 
"</pre>"
?> 


на экран они выводят хорошо. но мне нужно строку запроса из элементов массива собрать. как бы
это сделать попонятнее? test.xml в аттаче. на самом деле файл довольно большой

   
 
 автор: Trianon   (25.09.2006 в 18:45)   письмо автору
 
   для: elenaki   (25.09.2006 в 13:30)
 

Я бы пошел в следующем направлении:

Читал бы данные порциями от <ttt> до </ttt> обычным файловым чтением.
А затем добавив заголовок прогонял через парсер.
Данные вылавливал бы уже из структуры.

<?
$simple 
'<?xml version = "1.0" encoding="Windows-1253" standalone="yes"?>'.
"<ttt>
  <id>071287</id>
  <price>2898.30</price>
  <offer/>
  <availab>Y</availab>
  <famcat>ЕОБСФЗМБФБ-COMPONENTS-РБСЕЛКПМ</famcat>
  <subcat/>
  <manuf/>
  <marka/>
  <descr>ЕРЕО.INTEL CEL PRES 2.66G 533/256K 478B</descr>
  <retprice>0</retprice>
  <kerdos>0</kerdos>
  <eshop/>
  <apopou>QUEST</apopou>
</ttt>"
;
//$simple = "<para><note>simple note</note></para>";
$p xml_parser_create();
xml_parse_into_struct($p$simple$vals$index);
xml_parser_free($p);
echo 
"<pre>Index array\n";
print_r($index);
echo 
"\nVals array\n";
print_r($vals);
?>

   
 
 автор: elenaki   (25.09.2006 в 20:19)   письмо автору
 
   для: Trianon   (25.09.2006 в 18:45)
 

не вижу логики в этих массивах. начинаются нужные данные со второго индекса, нумерация скачет через 4 номера... с одной строкой справилась, а когда их много будет, откуда узнать, какой индекс вытягивать и где вообще надо остановиться. с массивами работала очень мало, с XML еще меньше :( а еще говорят, что XML проще, чем csv. пока не вижу в чем.

   
 
 автор: Trianon   (25.09.2006 в 21:02)   письмо автору
 
   для: elenaki   (25.09.2006 в 20:19)
 

А если так посмотреть?

$p = xml_parser_create();
xml_parse_into_struct($p, $simple, $vals, $index);
xml_parser_free($p);
foreach(array('ID','PRICE','OFFER','AVAILAB','FAMCAT','SUBCAT',
        'MANUF','MARKA','DESCR','RETPRICE','KERDOS','ESHOP','APOPOU') as $key)
{
   $val = $index[$key][0];
   echo "<br>$key : ";
   if(isset($vals[$val]['value']))
      echo  $vals[$val]['value'];
   else
      echo "---";
}

   
 
 автор: elenaki   (25.09.2006 в 21:12)   письмо автору
 
   для: Trianon   (25.09.2006 в 21:02)
 

Hy, это я видела и раньше. выводит то, что в первой паре тэгов <ttt></ttt>. а следующую как? а сотую? а тысячную? a BCE?

   
 
 автор: Trianon   (25.09.2006 в 21:24)   письмо автору
 
   для: elenaki   (25.09.2006 в 21:12)
 

а в принципе, индексы ttt-тегов будут перечислены в массиве $index['VFPDATA'],
конечно, для этого придется оставить этот уровень в исходном тексте.

   
 
 автор: Trianon   (25.09.2006 в 21:13)   письмо автору
 
   для: elenaki   (25.09.2006 в 20:19)
 

> а когда их много будет, откуда узнать, какой индекс вытягивать
А их не должно быть много. Каждую считанную порцию нужно парсить отдельно.
То есть можно конечно весь файл отпарсить, но если он большой, памяти может не хватить. Так что лучше - отдельно.

   
 
 автор: elenaki   (26.09.2006 в 15:55)   письмо автору
 
   для: Trianon   (25.09.2006 в 21:13)
 

нашла парсер, который парсит XML и дает мне инфу в нужном виде. одно плохо, пустые тэги типа </offer> или </subcat> (там, где нет никаких данных), он в упор не видит. а мне надо в запрос-то их все равно вставлять... что посоветуете? менять скриптом </offer> на <offer></offer>? или есть способ лучше? (парсер в аттаче, кому надо)

   
 
 автор: Trianon   (26.09.2006 в 17:12)   письмо автору
 
   для: elenaki   (26.09.2006 в 15:55)
 

У Вас пустые <offer/> а не </offer>

Можно так, например, сделать.

function startElement($parser, $name, $attrs)
{
    global $book, $inBook, $tagName;
    // esli vstretili nachalniy teg BOOK
    if ($name=="TTT")
    {
       // ukajem, chto mi v nem
        $inBook=true;
        $tagName = "";
    }
    else
    {
       if($inBook)
       {
              $tagName = $name;
              $book["$tagName"]='';
       }
    }
}

но метод всё равно аховый.
Вы представляете, что будет, если элементы в теге TTT пойдут в другом порядке?

   
 
 автор: elenaki   (26.09.2006 в 17:31)   письмо автору
 
   для: Trianon   (26.09.2006 в 17:12)
 

если элементы в теге TTT пойдут в другом порядке
=========================================
не пойдут. XML делается из VisualBasic. он может быть только в таком виде и ни в каком другом. это было главным условием.

Можно так, например, сделать.
==========================
не годится. вставляет пустое поле перед самым первым, перед id.


все равно, спасибо. вроде, разобралась. все грузит.

   
 
 автор: Trianon   (26.09.2006 в 17:51)   письмо автору
 
   для: elenaki   (26.09.2006 в 17:31)
 

Вот если бы foreach, перечисляющий поля опирался не на тег, а на список столбцов в базе, это пустое поле никто даже и не заметил бы. вообще-то я от него избавился, поставив
$book["$tagName"]=''; под условие.

Скрипт сильно напрашивается быть слегка измененным в сторону формирования одного оператора INSERT на много добавляемых строк. Возможно даже все сразу.

   
 
 автор: elenaki   (26.09.2006 в 19:28)   письмо автору
 
   для: Trianon   (26.09.2006 в 17:51)
 

Вот если бы foreach, перечисляющий поля опирался не на тег, а на список столбцов в базе, это пустое поле никто даже и не заметил бы. вообще-то я от него избавился, поставив
$book["$tagName"]=''; под условие.

==========================================================================

не поняла. столбцы в базе - те же, что и тэги внутри <ttt></ttt>. вы предлагаете перед values
в команде insert перечислять поля? только те, в которых есть значения? и только их и
вставлять?

Скрипт сильно напрашивается быть слегка измененным в сторону формирования одного оператора INSERT на много добавляемых строк. Возможно даже все сразу.
=========================================================================

мне кажется, по одной лучше. во всяком случае, при ошибке я сразу вижу, на какой строке
он споткнулся. а будет один запрос - скажет ошибка в строке 1 и где ее искать, если строка
на сотни тысяч символов?

   
 
 автор: Trianon   (26.09.2006 в 21:33)   письмо автору
 
   для: elenaki   (26.09.2006 в 19:28)
 

Я имел в виду нечто такое:

foreach(array('ID','PRICE','OFFER','AVAILAB','FAMCAT','SUBCAT',
        'MANUF','MARKA','DESCR','RETPRICE','KERDOS','ESHOP','APOPOU') as $name)
    {
         $val = $item[$name];
        // nazvanie polya i znachenie
       // print "\n<br><b>" . $name ."</b>&nbsp;&nbsp;&nbsp;". $val;


В случае многострокового запроса(его совсем необязательно вытягивать в одну строку):

xml_parser_free($xml_parser);

// cikl perebora knig
$query = '';
$line_sep  = "INSERT INTO price values \r\n" ;
foreach($books as $item)
{
    $query .= "$line_sep ";
    $line_sep = ",\r\n"

     $field_sep = "(";
    foreach(array('ID','PRICE','OFFER','AVAILAB','FAMCAT','SUBCAT',
        'MANUF','MARKA','DESCR','RETPRICE','KERDOS','ESHOP','APOPOU') as $name)
    {
         $val = $item[$name];
                // $name - nazvanie elementa
                // $val -  znachenie elementa
         $query .=  "$field_sep'".mysql_escape_string($val)."'";
         $field_sep = ",";
    }
    $query .= ')';
}

//echo $query;
$res = mysql_query($query);
if(!$res) die("error in insert request: [$query] ". mysql_error());

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования