PHP - İşleme Geçersiz XML

2 Cevap php

Ben bazı xml dosyaları yüklemek için SimpleXML kullanıyorum (/ sağlamak ben yazmadım ki ve gerçekten biçimini değiştiremezsiniz).

Bazen (dışında örneğin bir veya iki dosyaları her 50 ya da öylesine) herhangi bir özel karakter (çoğunlukla &, ama bazen diğer rasgele geçersiz şeyler de) kaçış yok. Php ile SimpleXML sadece başarısız olduğundan, bu ve sorun yaratır, ve ben gerçekten geçersiz XML ayrıştırma işlemek için iyi bir yol bilmiyorum.

Benim ilk fikir preprocess bir dize olarak XML ve çalışmak bu yüzden CDATA TÜM alanları koymak, ama bazı dinsiz nedenle ben süreci için gereken XML özniteliği alanlarındaki tüm verilerini koyar. Böylece ben CDATA fikri kullanamazsınız. XML olmanın bir örnek:

 <Author v="By Someone & Someone" />

Nedir ben SimpleXML ile yüklenemedi önce XML tüm geçersiz karakterleri değiştirmek için bu işlemek için en iyi yolu nedir?

2 Cevap

Ne gerek geçersiz karakterleri bulmak ve buna göre onları kaçmak için libxml'in iç kullanım hataları olacak bir şeydir. İşte ben bunu yazmak istiyorum nasıl bir mockup bulunuyor. libxml_get_errors() hata bilgi için sonuca bir göz atın.

function load_invalid_xml($xml)
{
    $use_internal_errors = libxml_use_internal_errors(true);
    libxml_clear_errors(true);

    $sxe = simplexml_load_string($xml);

    if ($sxe)
    {
        return $sxe;
    }

    $fixed_xml = '';
    $last_pos  = 0;

    foreach (libxml_get_errors() as $error)
    {
        // $pos is the position of the faulty character,
        // you have to compute it yourself
        $pos = compute_position($error->line, $error->column);
        $fixed_xml .= substr($xml, $last_pos, $pos - $last_pos) . htmlspecialchars($xml[$pos]);
        $last_pos = $pos + 1;
    }
    $fixed_xml .= substr($xml, $last_pos);

    libxml_use_internal_errors($use_internal_errors);

    return simplexml_load_string($fixed_xml);
}

i think workaroung for creating compute_position function will be make xml string flat before processing. Rewrite code posted by Josh:

function load_invalid_xml($xml)
{
    $use_internal_errors = libxml_use_internal_errors(true);
    libxml_clear_errors(true);

    $sxe = simplexml_load_string($xml);

    if ($sxe)
    {
        return $sxe;
    }

    $fixed_xml = '';
    $last_pos  = 0;

    // make string flat
    $xml = str_replace(array("\r\n", "\r", "\n"), "", $xml);

    // get file encoding
    $encoding = mb_detect_encoding($xml);

    foreach (libxml_get_errors() as $error)
    {
        $pos = $error->column;
        $invalid_char = mb_substr($xml, $pos, 1, $encoding);
        $fixed_xml .= substr($xml, $last_pos, $pos - $last_pos) . htmlspecialchars($invalid_char);
        $last_pos = $pos + 1;
    }
    $fixed_xml .= substr($xml, $last_pos);

    libxml_use_internal_errors($use_internal_errors);

    return simplexml_load_string($fixed_xml);
}

Ben sadece dizi [index] dize karakter alma yolu ile ilgili sorunlar yaşadım becose ben kodlama şeyler ekledim.

This all should work but, dont know why, i've seen that $error->column gives me a different number than it should. Trying to debug this by simply add some invalid characters inside xml and check what value it would return, but no luck with it. Hope someone could tell me what is wrong with this approach.