Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP4中XML解析/读取的使用方法_Php_Xml_Web Services - Fatal编程技术网

PHP4中XML解析/读取的使用方法

PHP4中XML解析/读取的使用方法,php,xml,web-services,Php,Xml,Web Services,不幸的是,我必须在PHP4服务器上的旧web应用程序中工作; 它现在需要解析大量的XML来调用webservices(定制协议,无SOAP/REST) 在PHP5下,我会使用SimpleXML,但这不可用; 在PHP4中有domxml,但在PHP5中不再是默认值 其他的选择是什么? 我正在寻找一种在迁移后仍能在PHP5上工作的解决方案 如果可以使用模式验证XML,则是一个不错的额外选项。有一个simpleXML后端口可用: 如果您可以安装它,那么这将是最好的解决方案。它可能有点草根,但如果它适用

不幸的是,我必须在
PHP4
服务器上的旧web应用程序中工作; 它现在需要解析大量的
XM
L来调用
webservices(定制协议,无SOAP/REST)

PHP5
下,我会使用
SimpleXML
,但这不可用; 在
PHP4
中有
domxml
,但在
PHP5
中不再是默认值

其他的选择是什么? 我正在寻找一种在迁移后仍能在
PHP5
上工作的解决方案


如果可以使用模式验证
XML
,则是一个不错的额外选项。

有一个simpleXML后端口可用:


如果您可以安装它,那么这将是最好的解决方案。

它可能有点草根,但如果它适用于您正在处理的数据,您可以使用XSLT将XML转换为可用的内容。显然,一旦升级到PHP5,XSLT仍然可以工作,并且可以在何时迁移到DOM解析

Andrew

我会支持simpleXML后端口,但如果这不是一个选项,那么将在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);

在PHP4中解析XML有一个很好的方法,可能对您有所帮助。

如果您可以使用XML\u parse,那么就去做吧。它健壮、快速,并且与PHP5兼容。但是,它不是一个DOM解析器,而是一个更简单的基于事件的解析器(),因此如果需要访问树,则必须自行将流封送到树中。这相当简单;使用s堆栈,并在
开始元素
上将项目推送到它,在
结束元素
上弹出项目,我绝对推荐SimpleXML backport,只要它的性能足以满足您的需要。xml_解析的演示看起来很简单,但根据我的经验,它很快就会变得非常复杂。内容处理程序函数不会获取有关解析器在树中的位置的任何上下文信息,除非您跟踪它并在开始和结束标记处理程序中提供它。因此,您要么为每个开始/结束标记调用函数,要么抛出全局变量来跟踪您在树中的位置


显然,SimeXML后端会慢一点,因为它是用PHP编写的,并且在它可用之前必须解析整个文档,但是编码的方便性比弥补它更容易。

也可以考虑查看PEAR中可用的XML包,特别是XMLUTIL、XMLX解析器,和XML_序列化程序…

将具有parse_to_struct的XML解析器转换为树数组结构:

<?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]);