2008-09-25 2 views
2

К сожалению, мне нужно работать в старом веб-приложении на сервере PHP4; Теперь необходимо разобрать XM L для звонка webservices (custom protocol, no SOAP/REST);Что использовать для XML-анализа/чтения в PHP4

Под PHP5 Я бы использовал SimpleXML, но это не доступно; Существует Dom XML в PHP4, но он не является по умолчанию в PHP5.

Какие существуют другие варианты? Я ищу решение, которое по-прежнему работает на PHP5 после их миграции.

Приятно, если XML может быть проверен со схемой.

ответ

0

Это может быть немного нисходящим, но если это применимо к данным, с которыми вы работаете, вы можете использовать XSLT для преобразования своего XML в нечто пригодное для использования. Очевидно, как только вы перейдете на PHP5, XSLT все равно будет работать, и вы сможете перенести, когда и когда на разбор DOM.

Эндрю

2

Я бы второй Rich Bradshaw's suggestion о Backport SimpleXML, но если это не вариант, то xml_parse будет выполнять работу в PHP4, и по-прежнему работает после миграции 5.

$xml = ...; // Get your XML data 
$xml_parser = xml_parser_create(); 

// _start_element and _end_element are two functions that determine what 
// to do when opening and closing tags are found 
xml_set_element_handler($xml_parser, "_start_element", "_end_element"); 

// How to handle each char (stripping whitespace if needs be, etc 
xml_set_character_data_handler($xml_parser, "_character_data"); 

xml_parse($xml_parser, $xml); 

Там в хороший tutorial here о разборе XML в PHP4, который может вам пригодиться.

0

Если вы можете использовать xml_parse, то для этого перейдите. Он прочный, быстрый и совместимый с PHP5. Это, однако, не парсер DOM, а более простой, основанный на событиях (Also called a SAX parser), поэтому, если вам нужно получить доступ к дереву, вам придется вручную вывести поток в дерево. Это довольно просто сделать; Используйте s stack и нажимайте на него предметы на start-element и нажмите на end-element.

0

Я бы определенно рекомендовал обратный порт SimpleXML, если его производительность достаточно для ваших нужд. Демонстрации xml_parse выглядят достаточно простыми, но в моем опыте очень быстро получается очень волосатый. Функции обработчика содержимого не получают никакой контекстной информации о том, где синтаксический анализатор находится в дереве, если вы не отслеживаете его и не предоставляете его в обработчиках начального и конечного тегов. Таким образом, вы либо вызываете функции для каждого тэга start/end, либо бросаете вокруг глобальных переменных, чтобы отслеживать, где вы находитесь в дереве.

Очевидно, что обратный ход SimpleXML будет немного медленнее, поскольку он написан на PHP и должен анализировать весь документ до его доступности, но простота кодирования более чем компенсирует его.

0

Может также рассмотреть глядя на пакеты XML, доступные в PEAR, особенно XML_Util, XML_Parser и XML_Serializer ...

0

XML Parser с parse_into_struct превратилась в структуру дерева массива:

<?php 
/** 
* What to use for XML parsing/reading in PHP4 
* @link http://stackoverflow.com/q/132233/367456 
*/ 

$encoding = 'US-ASCII'; 
     // https://gist.github.com/hakre/46386de578619fbd898c 
$path  = dirname(__FILE__) . '/time-series-example.xml'; 

$parser_creator = 'xml_parser_create'; // alternative creator is 'xml_parser_create_ns' 

if (!function_exists($parser_creator)) { 
    trigger_error(
     "XML Parsers' $parser_creator() not found. XML Parser " 
     . '<http://php.net/xml> is required, activate it in your PHP configuration.' 
     , E_USER_ERROR 
    ); 
    return; 
} 

$parser = $parser_creator($encoding); 
if (!$parser) { 
    trigger_error(sprintf('Unable to create a parser (Encoding: "%s")', $encoding), E_USER_ERROR); 
    return; 
} 

xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); 
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); 

$data = file_get_contents($path); 
if ($data === FALSE) { 
    trigger_error(sprintf('Unable to open file "%s" for reading', $path)); 
    return; 
} 
$result = xml_parse_into_struct($parser, $data, $xml_struct_values); 
unset($data); 
xml_parser_free($parser); 
unset($parser); 

if ($result === 0) { 
    trigger_error(sprintf('Unable to parse data of file "%s" as XML', $path)); 
    return; 
} 

define('TREE_NODE_TAG', 'tagName'); 
define('TREE_NODE_ATTRIBUTES', 'attributes'); 
define('TREE_NODE_CHILDREN', 'children'); 

define('TREE_NODE_TYPE_TAG', 'array'); 
define('TREE_NODE_TYPE_TEXT', 'string'); 
define('TREE_NODE_TYPE_NONE', 'NULL'); 

/** 
* XML Parser indezies for parse into struct values 
*/ 
define('XML_STRUCT_VALUE_TYPE', 'type'); 
define('XML_STRUCT_VALUE_LEVEL', 'level'); 
define('XML_STRUCT_VALUE_TAG', 'tag'); 
define('XML_STRUCT_VALUE_ATTRIBUTES', 'attributes'); 
define('XML_STRUCT_VALUE_VALUE', 'value'); 

/** 
* XML Parser supported node types 
*/ 
define('XML_STRUCT_TYPE_OPEN', 'open'); 
define('XML_STRUCT_TYPE_COMPLETE', 'complete'); 
define('XML_STRUCT_TYPE_CDATA', 'cdata'); 
define('XML_STRUCT_TYPE_CLOSE', 'close'); 

/** 
* Tree Creator 
* @return array 
*/ 
function tree_create() 
{ 
    return array(
     array(
      TREE_NODE_TAG  => NULL, 
      TREE_NODE_ATTRIBUTES => NULL, 
      TREE_NODE_CHILDREN => array(), 
     ) 
    ); 
} 

/** 
* Add Tree Node into Tree a Level 
* 
* @param $tree 
* @param $level 
* @param $node 
* @return array|bool Tree with the Node added or FALSE on error 
*/ 
function tree_add_node($tree, $level, $node) 
{ 
    $type = gettype($node); 
    switch ($type) { 
     case TREE_NODE_TYPE_TEXT: 
      $level++; 
      break; 
     case TREE_NODE_TYPE_TAG: 
      break; 
     case TREE_NODE_TYPE_NONE: 
      trigger_error(sprintf('Can not add Tree Node of type None, keeping tree unchanged', $type, E_USER_NOTICE)); 
      return $tree; 
     default: 
      trigger_error(sprintf('Can not add Tree Node of type "%s"', $type), E_USER_ERROR); 
      return FALSE; 
    } 

    if (!isset($tree[$level - 1])) { 
     trigger_error("There is no parent for level $level"); 
     return FALSE; 
    } 

    $parent = & $tree[$level - 1]; 

    if (isset($parent[TREE_NODE_CHILDREN]) && !is_array($parent[TREE_NODE_CHILDREN])) { 
     trigger_error("There are no children in parent for level $level"); 
     return FALSE; 
    } 

    $parent[TREE_NODE_CHILDREN][] = & $node; 
    $tree[$level]     = & $node; 

    return $tree; 
} 

/** 
* Creator of a Tree Node 
* 
* @param $value XML Node 
* @return array Tree Node 
*/ 
function tree_node_create_from_xml_struct_value($value) 
{ 
    static $xml_node_default_types = array(
     XML_STRUCT_VALUE_ATTRIBUTES => NULL, 
     XML_STRUCT_VALUE_VALUE  => NULL, 
    ); 

    $orig = $value; 

    $value += $xml_node_default_types; 

    switch ($value[XML_STRUCT_VALUE_TYPE]) { 
     case XML_STRUCT_TYPE_OPEN: 
     case XML_STRUCT_TYPE_COMPLETE: 
      $node = array(
       TREE_NODE_TAG => $value[XML_STRUCT_VALUE_TAG], 
       // '__debug1' => $orig, 
      ); 
      if (isset($value[XML_STRUCT_VALUE_ATTRIBUTES])) { 
       $node[TREE_NODE_ATTRIBUTES] = $value[XML_STRUCT_VALUE_ATTRIBUTES]; 
      } 
      if (isset($value[XML_STRUCT_VALUE_VALUE])) { 
       $node[TREE_NODE_CHILDREN] = (array)$value[XML_STRUCT_VALUE_VALUE]; 
      } 
      return $node; 

     case XML_STRUCT_TYPE_CDATA: 
      // TREE_NODE_TYPE_TEXT 
      return $value[XML_STRUCT_VALUE_VALUE]; 

     case XML_STRUCT_TYPE_CLOSE: 
      return NULL; 

     default: 
      trigger_error(
       sprintf(
        'Unkonwn Xml Node Type "%s": %s', $value[XML_STRUCT_VALUE_TYPE], var_export($value, TRUE) 
       ) 
      ); 
      return FALSE; 
    } 
} 

$tree = tree_create(); 

while ($tree && $value = array_shift($xml_struct_values)) { 
    $node = tree_node_create_from_xml_struct_value($value); 
    if (NULL === $node) { 
     continue; 
    } 
    $tree = tree_add_node($tree, $value[XML_STRUCT_VALUE_LEVEL], $node); 
    unset($node); 
} 

if (!$tree) { 
    trigger_error('Parse error'); 
    return; 
} 

if ($xml_struct_values) { 
    trigger_error(sprintf('Unable to process whole parsed XML array (%d elements left)', count($xml_struct_values))); 
    return; 
} 

// tree root is the first child of level 0 
print_r($tree[0][TREE_NODE_CHILDREN][0]); 

Выход:

Array 
(
    [tagName] => dwml 
    [attributes] => Array 
     (
      [version] => 1.0 
      [xmlns:xsd] => http://www.w3.org/2001/XMLSchema 
      [xmlns:xsi] => http://www.w3.org/2001/XMLSchema-instance 
      [xsi:noNamespaceSchemaLocation] => http://www.nws.noaa.gov/forecasts/xml/DWMLgen/schema/DWML.xsd 
     ) 

    [children] => Array 
     (
      [0] => Array 
       (
        [tagName] => head 
        [children] => Array 
         (
          [0] => Array 
           (
            [tagName] => product 
            [attributes] => Array 
             (
              [srsName] => WGS 1984 
              [concise-name] => time-series 
              [operational-mode] => official 
             ) 

            [children] => Array 
             (
              [0] => Array 
               (
                [tagName] => title 
                [children] => Array 
                 (
                  [0] => NOAA's National Weather Service Forecast Data 
                 ) 

               ) 

              [1] => Array 
               (
                [tagName] => field 
                [children] => Array 
                 (
                  [0] => meteorological 
                 ) 

               ) 

              [2] => Array 
               (
                [tagName] => category 
                [children] => Array 
                 (
                  [0] => forecast 
                 ) 

               ) 

              [3] => Array 
               (
                [tagName] => creation-date 
                [attributes] => Array 
                 (
                  [refresh-frequency] => PT1H 
                 ) 

                [children] => Array 
                 (
                  [0] => 2013-11-02T06:51:17Z 
                 ) 

               ) 

             ) 

           ) 

          [1] => Array 
           (
            [tagName] => source 
            [children] => Array 
             (
              [0] => Array 
               (
                [tagName] => more-information 
                [children] => Array 
                 (
                  [0] => http://www.nws.noaa.gov/forecasts/xml/ 
                 ) 

               ) 

              [1] => Array 
               (
                [tagName] => production-center 
                [children] => Array 
                 (
                  [0] => Meteorological Development Laboratory 
                  [1] => Array 
                   (
                    [tagName] => sub-center 
                    [children] => Array 
                     (
                      [0] => Product Generation Branch 
                     ) 

                   ) 

                 ) 

               ) 

              [2] => Array 
               (
                [tagName] => disclaimer 
                [children] => Array 
                 (
                  [0] => http://www.nws.noaa.gov/disclaimer.html 
                 ) 

               ) 

              [3] => Array 
               (
                [tagName] => credit 
                [children] => Array 
                 (
                  [0] => http://www.weather.gov/ 
                 ) 

               ) 

              [4] => Array 
               (
                [tagName] => credit-logo 
                [children] => Array 
                 (
                  [0] => http://www.weather.gov/images/xml_logo.gif 
                 ) 

               ) 

              [5] => Array 
               (
                [tagName] => feedback 
                [children] => Array 
                 (
                  [0] => http://www.weather.gov/feedback.php 
                 ) 

               ) 

             ) 

           ) 

         ) 

       ) 

      [1] => Array 
       (
        [tagName] => data 
        [children] => Array 
         (
          [0] => Array 
           (
            [tagName] => location 
            [children] => Array 
             (
              [0] => Array 
               (
                [tagName] => location-key 
                [children] => Array 
                 (
                  [0] => point1 
                 ) 

               ) 

              [1] => Array 
               (
                [tagName] => point 
                [attributes] => Array 
                 (
                  [latitude] => 40.00 
                  [longitude] => -120.00 
                 ) 

               ) 

             ) 

           ) 

          [1] => Array 
           (
            [tagName] => moreWeatherInformation 
            [attributes] => Array 
             (
              [applicable-location] => point1 
             ) 

            [children] => Array 
             (
              [0] => http://forecast.weather.gov/MapClick.php?textField1=40.00&textField2=-120.00 
             ) 

           ) 

          [2] => Array 
           (
            [tagName] => time-layout 
            [attributes] => Array 
             (
              [time-coordinate] => local 
              [summarization] => none 
             ) 

            [children] => Array 
             (
              [0] => Array 
               (
                [tagName] => layout-key 
                [children] => Array 
                 (
                  [0] => k-p24h-n4-1 
                 ) 

               ) 

              [1] => Array 
               (
                [tagName] => start-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-02T08:00:00-07:00 
                 ) 

               ) 

              [2] => Array 
               (
                [tagName] => end-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-02T20:00:00-07:00 
                 ) 

               ) 

              [3] => Array 
               (
                [tagName] => start-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-03T07:00:00-08:00 
                 ) 

               ) 

              [4] => Array 
               (
                [tagName] => end-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-03T19:00:00-08:00 
                 ) 

               ) 

              [5] => Array 
               (
                [tagName] => start-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-04T07:00:00-08:00 
                 ) 

               ) 

              [6] => Array 
               (
                [tagName] => end-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-04T19:00:00-08:00 
                 ) 

               ) 

              [7] => Array 
               (
                [tagName] => start-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-05T07:00:00-08:00 
                 ) 

               ) 

              [8] => Array 
               (
                [tagName] => end-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-05T19:00:00-08:00 
                 ) 

               ) 

             ) 

           ) 

          [3] => Array 
           (
            [tagName] => time-layout 
            [attributes] => Array 
             (
              [time-coordinate] => local 
              [summarization] => none 
             ) 

            [children] => Array 
             (
              [0] => Array 
               (
                [tagName] => layout-key 
                [children] => Array 
                 (
                  [0] => k-p24h-n5-2 
                 ) 

               ) 

              [1] => Array 
               (
                [tagName] => start-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-01T20:00:00-07:00 
                 ) 

               ) 

              [2] => Array 
               (
                [tagName] => end-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-02T09:00:00-07:00 
                 ) 

               ) 

              [3] => Array 
               (
                [tagName] => start-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-02T19:00:00-07:00 
                 ) 

               ) 

              ... 

              [10] => Array 
               (
                [tagName] => end-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-06T08:00:00-08:00 
                 ) 

               ) 

             ) 

           ) 

          [4] => Array 
           (
            [tagName] => time-layout 
            [attributes] => Array 
             (
              [time-coordinate] => local 
              [summarization] => none 
             ) 

            [children] => Array 
             (
              [0] => Array 
               (
                [tagName] => layout-key 
                [children] => Array 
                 (
                  [0] => k-p12h-n9-3 
                 ) 

               ) 

              [1] => Array 
               (
                [tagName] => start-valid-time 
                [children] => Array 
                 (
                  [0] => 2013-11-01T17:00:00-07:00 
                 ) 

               ) 
            ... 
Смежные вопросы