重置 XML 解析器 PHP

发布于 2024-09-08 11:05:32 字数 3450 浏览 2 评论 0原文

您好,我正在使用一个类来解析我的 XML。

我必须解析请求 XML 和响应 XML,并且我想使用相同的解析器来完成此操作。当我解析响应 XML 时,我不断收到 junk after document element 错误。

我将 XML 缩小到 但我仍然收到错误,所以我唯一能想到的是第二个 标头被解析为“垃圾”。

我基本上想做的是重置 XML 解析器,以便它可以作为新文档启动,但我不想创建新的解析器对象。这可能吗?

编辑:

我在 XmlParser 对象中使用以下代码。

<?php
    class XmlComponent extends Object {
        private $parser, $c, $current_tag;
        public $contents;

        function initialize(&$controller, $settings = array())
        {
            $this->controller =& $controller;
            $this->parser = xml_parser_create();
            xml_set_object($this->parser, $this);
            xml_set_element_handler($this->parser, "tag_open", "tag_close");
            xml_set_character_data_handler($this->parser, "cdata");
            xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);

            if (isset($settings['xml'])) { 
                $contents = $settings['xml'];
            }
            if (isset($settings['file'])) {
                $f = fopen($settings['file'], 'r');
                $contents = fread($f, filesize($settings['file']));
                fclose($f);
            }

            debug($this->parse($contents));

        }

        public function parse($xml)
        {

            $xml = trim(preg_replace("/>\s+</", '><', $xml));
            $this->contents = array();
            $this->c = &$this->contents;
            xml_parse($this->parser, $xml);
            return xml_error_string(xml_get_error_code($this->parser))."\r\n".$xml;
        }

        //*/
        public function xml($root)
        {
            $xml = '';
            foreach ($root as $tag=>$elem) {
                if (substr($tag, 0,1) != '@') {
                    foreach ($elem as $val) {
                        $xml .= '<'.$tag;
                        if (is_array($val) && isset($val['@attributes'])) {
                            foreach($val['@attributes'] as $a_key => $a_val) {
                                $xml .= ' '.$a_key.'="'.$a_val.'"';
                            }
                        }
                        $xml .= '>';
                        if (is_array($val) && isset($val['@data'])) {
                            $xml .= $val['@data'];
                        }
                        $xml .= $this->xml($val);
                        $xml .= '</'.$tag.'>';
                    }
                }
            }

            return $xml;
        }
        //*/

        private function tag_open($parser, $tag, $attributes)
        {
            if (!empty($attributes)) { $this->c[$tag][] = array('@attributes' => $attributes, '@parent' => &$this->c); }
            else { $this->c[$tag][] = array('@parent' => &$this->c); }

            $this->c =& $this->c[$tag][count($this->c[$tag]) - 1];

        }

        private function tag_close($parser, $tag)
        {
            $parent = &$this->c['@parent'];
            unset($this->c['@parent']);
            $this->c =& $parent;
        }

        private function cdata($parser, $data)
        {
            if (!empty($data)) {$this->c['@data'] = $data;}
        }
        //*/

    }
?>

Hi I'm using a class to parse my XML.

I have to parse request XML and response XML, and I'd like to do it with the same parser. When I parse the response XML, I keep getting junk after document element error.

I narrowed my XML down to <?xml version="1.0" encoding="UTF-8" ?><check></check> and I'm still getting the error, so the only thing I could think of is the second <?xml ..?> header being parsed as 'junk'.

What I basically want to do is reset the XML parser so it can start off as a new document, but I don't want to create a new parser object. Is this possible?

Edit:

I'm using the following code in my XmlParser object.

<?php
    class XmlComponent extends Object {
        private $parser, $c, $current_tag;
        public $contents;

        function initialize(&$controller, $settings = array())
        {
            $this->controller =& $controller;
            $this->parser = xml_parser_create();
            xml_set_object($this->parser, $this);
            xml_set_element_handler($this->parser, "tag_open", "tag_close");
            xml_set_character_data_handler($this->parser, "cdata");
            xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);

            if (isset($settings['xml'])) { 
                $contents = $settings['xml'];
            }
            if (isset($settings['file'])) {
                $f = fopen($settings['file'], 'r');
                $contents = fread($f, filesize($settings['file']));
                fclose($f);
            }

            debug($this->parse($contents));

        }

        public function parse($xml)
        {

            $xml = trim(preg_replace("/>\s+</", '><', $xml));
            $this->contents = array();
            $this->c = &$this->contents;
            xml_parse($this->parser, $xml);
            return xml_error_string(xml_get_error_code($this->parser))."\r\n".$xml;
        }

        //*/
        public function xml($root)
        {
            $xml = '';
            foreach ($root as $tag=>$elem) {
                if (substr($tag, 0,1) != '@') {
                    foreach ($elem as $val) {
                        $xml .= '<'.$tag;
                        if (is_array($val) && isset($val['@attributes'])) {
                            foreach($val['@attributes'] as $a_key => $a_val) {
                                $xml .= ' '.$a_key.'="'.$a_val.'"';
                            }
                        }
                        $xml .= '>';
                        if (is_array($val) && isset($val['@data'])) {
                            $xml .= $val['@data'];
                        }
                        $xml .= $this->xml($val);
                        $xml .= '</'.$tag.'>';
                    }
                }
            }

            return $xml;
        }
        //*/

        private function tag_open($parser, $tag, $attributes)
        {
            if (!empty($attributes)) { $this->c[$tag][] = array('@attributes' => $attributes, '@parent' => &$this->c); }
            else { $this->c[$tag][] = array('@parent' => &$this->c); }

            $this->c =& $this->c[$tag][count($this->c[$tag]) - 1];

        }

        private function tag_close($parser, $tag)
        {
            $parent = &$this->c['@parent'];
            unset($this->c['@parent']);
            $this->c =& $parent;
        }

        private function cdata($parser, $data)
        {
            if (!empty($data)) {$this->c['@data'] = $data;}
        }
        //*/

    }
?>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

缪败 2024-09-15 11:05:32

我基本上想做的是重置 XML 解析器,以便它可以作为新文档启动,但我不想创建新的解析器对象。这可能吗?

不,您必须创建一个新的解析器。当然,您可以在您的类中提供一个“重置”解析器的方法;即,删除当前的并创建一个新的,从而对类使用者隐藏它。

What I basically want to do is reset the XML parser so it can start off as a new document, but I don't want to create a new parser object. Is this possible?

No, you have to create a new parser. You can, of course, provide in your class a method that "resets" the parser; i.e., deletes the current one and creates a new one, hence hiding it from the class consumer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文