PHP XML Parser xml_set_default_handler разделяет специальный символ - PullRequest
1 голос
/ 02 января 2012

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

$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);

xml_set_element_handler($parser, "startTag", "endTag");
xml_set_default_handler($parser, 'defaultHandler');


function startTag($p, $name, $attributes)
{

}

function endTag($p, $name)
{

}

function defaultHandler($parser, $data)
{
    if(strlen(trim($data)) > 0)
        echo '[' . $data . ']' . '<br />';
}                                                                                                                        

Пример XML:

<variable name="GZH29" type="integer">
    <label>This is a small test with a special ë character. Let's try an ë character too</label>
</variable>

Можно было бы ожидать:

[This is a small test with a special ë character. Let's try an ë character too]

Но результат равен

[This is a small test with a special ]
[ë character. Let's try an ë character too]

Я бы не хотел разбивать строку, поэтому есть идеи, каково решение?

1 Ответ

0 голосов
/ 02 января 2012

xml_parser создает здесь несколько событий по причине, которую я до конца не понял, я думаю, что это из-за автоопределения кодировки.

Вы можете справиться с этим, создав свой собственныйкласс парсера.Это вообще полезно в любом случае, не только в этом случае.Но для этого случая особенно важно, чтобы вы могли собрать текст метки, которая будет распределена по нескольким событиям.

Основная работа - сделать функции обратного вызова общедоступной функцией класса, а затем зарегистрировать эти функции.

Затем каждый раз, когда открывается тег label, временное хранилище сбрасывается.Когда появляется текст, он добавляется во временное хранилище.Если тег label закрывается, вы можете передать этот текст новому «событию», на этот раз функции, которую вы ищете, с ее текстом:

$variableParser = new VariableParser($parser);

$file = 'data://,'.$xml;
$fp = fopen($file, 'r');
while(!feof($fp)) { $data = fread($fp, 4096); xml_parse($parser, $data, feof($fp)); }


class VariableParser
{
    private $label = ''; # place for the label text
    public function doLabel($text)
    {
        printf("[%s]<br />\n", $text);
    }
    public function __construct($parser = NULL)
    {
        if ($parser) $this->register($parser);
    }
    public function register($parser)
    {
        xml_set_element_handler($parser, array($this, "startTag"), array($this, "endTag"));
        xml_set_default_handler($parser, array($this, 'defaultHandler'));
    }

    public function startTag($parser, $name, $attributes)
    {
        if ($name === 'label') $this->label = '';
    }

    function endTag($parser, $name)
    {
        if ($name === 'label')
        {
            $this->doLabel($this->label);
            $this->label = '';
        }
    }

    function defaultHandler($parser, $data)
    {
        if(strlen(trim($data)) > 0)
        {
            $this->label .= $data;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...