Hata Toleranslı HTML / XML / SGML PHP ayrıştırma

7 Cevap php

Ben HTML gibi eski belgeler bir grup var. Olduğu gibi, onlar HTML gibi görünür, ama HTML bir parçası olmayan ilave yapılmış etiketleri var

<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>

Ben bu dosyaları ayrıştırmak gerekiyor. PHP mevcut yalnızca araçtır. Belgeler iyi oluşturulmuş XML olan yakın gelmiyor.

Benim orijinal düşünce PHPs DOMDocument üzerinde loadHTML yöntemleri kullanmak oldu. Ancak, bu yöntemler makyaj HTML etiketleri boğulmamak ve dize / dosyayı ayrıştırmak reddeder.

$oDom = new DomDocument();
$oDom->loadHTML("<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>");
//gives us
DOMDocument::loadHTML() [function.loadHTML]: Tag pseud-template invalid in Entity, line: 1 occured in ....

Ben gelmek mümkün oldum tek çözüm ön-işlem geçersiz etiketlerini kaldırmak ve geçerli bir HTML etiketi (etiket adı bir kimliği ile belki de bir yayılma) ile yerini alacak dize değiştirme fonksiyonları ile dosyaları etmektir.

Daha zarif bir çözüm var mı? DOMDocument geçerli dikkate ek etiketleri bildirmek için bir yolu? PHP için orada farklı, sağlam bir HTML ayrıştırma sınıf / nesne var mı?

(Çok açık değilse, ben burada normal ifadeler geçerli bir çözüm düşünmüyoruz)

Update: Sahte etiketleri bilgiler burada amacın bir parçası, yani Tidy gibi bir şey bir seçenek değildir. Ayrıca, yaptığı bir şeyin peşindeyim bazı düzeyi, hepsi değilse de, ben ilk etapta DOMDocument en loadHTML yöntemi arıyordum neden benim için iyi biçimlilik temizleme,.

7 Cevap

Ben üzerinden "kötü" HTML Geçen eğer HTML Tidy bir ilk geçiş olarak yardımcı olabilir acaba? Eğer belge de oluşturulabilir alabilirsiniz eğer, belki domBelgesi ile normal bir XML dosyası olarak yük olabilir, bir göz değer olabilir.

@Twan You don't need a DTD for DOMDocument to parse custom XML. Just use DOMDocument->load(), and as long as the XML is well-formed, it can read it.

Eğer dosyaları iyi biçimlendirilmiş olması kez sen almak XML ayrıştırıcıları bakarak başlayabilirsiniz zaman önce SOL konum, işte o Lok Alejo Eğer HTML TIDY bakmak olabilir, dedi, ama bu HTML özgü var gibi görünüyor, ve ben sizin özel elemanlar ile gitmek istiyorum nasıl bilmiyorum.

Burada normal ifadeler geçerli bir çözüm düşünmüyoruz

Eğer iyi biçimlilik var Ta ki tek seçenek olabilir. Eğer o aşamaya belgeleri aldıktan sonra, daha sonra DOM fonksiyonları ile açık konum.

PHP Fit limanda Ayrıştırıcı bir göz atın. Kodu temiz ve orijinal Word tarafından kaydedilen kirli HTML yüklenmesi için tasarlanmıştır. Bu tablolar çekin yapılandırılmış, ancak kolayca adapated edilebilir.

You can see the source here: http://gerd.exit0.net/pat/PHPFIT/PHPFIT-0.1.0/Parser.phps

The unit test will show you how to use it: http://gerd.exit0.net/pat/PHPFIT/PHPFIT-0.1.0/test/parser.phps

Eğer tidyHTML (tidy.sourceforge.net) denediniz mi? Ben PHP için geçerli olduğunu düşünüyorum ve ve oldukça iyi bir ayrıştırıcı bulunuyor

Bu sorunun benim hızlı ve kirli çözüm düzenli bir ifade ile özel etiketler listemi eşleşen bir döngü çalıştırmak oldu. Sıradanifade içlerinde başka bir iç özel etiketine sahip etiketlerini yakalamak değildir.

Bir maç olduğunda, bu etiketi işlemek için bir işlevi olarak adlandırılır ve "işlenmiş HTML" döndürür. Bu özel etiket ebeveyn gerçek HTML çocuğun yerine yerleştirildi ve regexp ile eşleşen ve döngünün sonraki yineleme işlenmiş olacağı gerçeği ile çocuksuz olur başka bir özel etiket içinde olsaydı.

Uyumlu olması için hiçbir çocuksuz özel etiketler olduğunda döngü sona erer. Genel tekrarlanan (bir süre döngü) ve özyinelemeli değil.

@ Alan Fırtına

Benim diğer yanıt hakkındaki yorumunuz düşünme beni var:

Eğer DOMDocument ile bir HTML dosyası yüklediğinizde, bu temizleme yeniden belli bir düzeyde yapmak için görünür: iyi iyi biçimlilik, ANCAK okunaklı HTML etiketleri olmak üzere tüm etiketleri gerektirir. Ben eski bir şey için arıyor, ancak daha sonra değilim. (Alan Fırtına)

(Belgelerden herhangi bulunmayan etiketler üzerinde bir regex (kusura bakmayın) çalıştırın ve geçerli bir HTML öğesi olmadığı bulduğunda, sizin bildiğiniz geçerli bir elemanı ile değiştirin {[(0)] } geri sonradan geçiş yapabilirsiniz, böylece) ... zihin ve yasadışı elemanın adı ile bir öznitelik değeri vermek için geliyor. örneğin:

$code = str_replace("<pseudo-tag>", "<blink rel=\"pseudo-tag\">", $code);
// and then back again...
$code = preg_replace('<blink rel="(.*?)">', '<\1>', $code);

Açıkçası bu kod çalışmaz, ama genel bir fikir olsun?