2012-01-02 95 views
1

PHP的XML解析器調用默認處理函數兩次當它遇到字符串中的特殊字符,因此分裂的字符串。我試着在PHP代碼中使用不同的編碼在XML頭一樣好解決,但它仍然分裂的字符串:PHP XML解析器xml_set_default_handler分裂特殊字符

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

人們期望:該XML的

$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 />'; 
}                               

例:

[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] 

我想不要分割線,所以不知道解決方案是什麼?

回答

0

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; 
     } 
    } 
} 
+0

我想提取每個'的XML的label'標籤轉換爲一個字符串並將其插入到數據庫中。我也用'xml_set_character_data_handler'試過了它,但它給出了相同的結果。這是一個包含1000個這樣的'variable'和'label'標籤的大型XML文件。 – Postie 2012-01-03 07:05:40

+0

一個可能的選項:將目標編碼設置爲UTF-8 - 它具有所有字符並且不需要實體 - 並且在獲得UTF-8文本後,將其重新編碼爲ISO-8859-1,可能在您贏得音頻時進行轉碼無法將文本的每個字符作爲Latin-1插入到數據庫中。聽起來很實際? – hakre 2012-01-03 08:24:09

+0

我已經嘗試了幾種編碼方式來編譯目標和源代碼。將XML編碼更改爲UTF,但仍然無效。奇怪的是,它只會在第一個特殊字符上打破。 不知道PHP中的XMLReader類,更改了代碼以使用該類,這沒有任何問題。 – Postie 2012-01-03 08:50:00