HTML varlıklarının kodunu çözmenin yerleşik yolu (yani "veya" 39)


11

Son zamanlarda html varlıklarını çözme sorunuyla karşılaştım. Aşağıdaki iki dize var ( nasıl kodlama, adlandırılmış ve numaralı iki yöntem kullanılır unutmayın ).

The old "how to fold xml" question
Babel doesn't wrap results in verbatim

Ve onları

The old "how to fold xml" question
Babel doesn't wrap results in verbatim

Etrafa bakarken, SO hakkında şu eski soruyu buldum (şu an yaptığım şey budur, ancak Emacs'ın bunu yapmanın yerleşik bir yolu olmadığına inanmayı reddediyorum. Posta istemcilerinden ve özet akışı okuyucularından bahsetmemek için, en az ikisi yerleşik olduğunu bildiğim birkaç web tarayıcımız var.

Html varlıklarını çözmenin yerleşik bir yolu yok mu?
İlk örnekten bir dize alır ve ikinci örnekten bir dize döndüren bir işlev arıyorum.


Bir şey varsa, DTD'leri ayrıştırabildiği ve belgedeki varlıkları doğrulayabildiği için nxml kodunda olması gerektiğine bahse girerim.
wasamasa

libxml-parse-html-regionBunu elbette yapar, ancak HTML etiketlerini de ayrıştırması nedeniyle istediğinizden daha fazlasını yapabilir… (Ve tüm Emacs'ın da LibXML desteği ile inşa edilmediğini düşünüyorum).
Jon O.

Yanıtlar:


7

Emacs, işlevi işini xml.elyapan saf Elisp XML ayrıştırıcısını içeriyor xml-parse-string, ancak biraz belgelenmemiş bir iç işlev gibi görünüyor. Dize bir XML parçası olarak ele alındığında düzgün işlenmeyecek yalnızca HTML varlıkları olup olmadığından emin değilim.

Bu sarmalayıcı işlevi, daha sıkı hale getirebilmenize rağmen, giriş dizesindeki herhangi bir sondaki etiketi atlar:

(defun decode-entities (html)
  (with-temp-buffer
    (save-excursion (insert html))
    (xml-parse-string)))

(decode-entities "The old "how to fold xml" question")
;; => "The old \"how to fold xml\" question"

(decode-entities "doesn't")
;; => "doesn't"

(decode-entities "string with trailing tag: <tag/>")
;; => "string with trailing tag: "

LibXML desteğine sahip Emacs'ta, biraz hackish başka bir yol, bir sarmalayıcı yazmak olacaktır libxml-html-parse-region. LibXML ayrıştırıcısı bağımsız değişkeninin tam bir HTML belgesi olduğunu varsaydığından, sarma işlevinin kullanarak ayrıştırılmış karakter verilerini döndürülen belge yapısından ayıklaması gerekir pcase. Herhangi bir HTML etiketi içeren bir dizeyi deşifre etmeye çalışmak bir hataya neden olur:

(defun decode-entities/libxml (html)
  (with-temp-buffer
    (insert html)
    (let ((document
           (libxml-parse-html-region (point-min) (point-max))))
      (pcase document
        (`(html nil
                (body nil
                      (p nil
                         ,(and (pred stringp)
                               content))))
          content)
        (_ (error "Unexpected parse result: %S" document))))))

Sonuçlar:

(decode-entities/libxml "The old &quot;how to fold xml&quot; question")
     ; => "The old \"how to fold xml\" question"
(decode-entities/libxml "doesn&#39;t") ; => "doesn't"

(decode-entities/libxml "<html>")              ; produces an error

Bir belge parçasını tam bir belge olarak ayrıştırarak, yalnızca çevredeki etiketleri derhal çıkarmak için biraz geriye doğru görünüyor. Öte yandan, LibXML kullanmak hızlı olmalı ve doğru sonuçlar vermelidir.


Üzgünüz, xml düzenlemenizi görmedim. Harika görünüyor.
Malabarba

Teşekkürler - Cevabı daha basit bir xml.elçözüm haline getirmek için düzenledim .
Jon O.

@Malabarba lisp/xml.elHer zaman Jon O. ilexml-substitute-special aynı kod çözme işlevini gerçekleştiren işlevi içerir . Ancak, sondaki etiketleri atlamaz. decode-entities
Fesleğen

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.