2014-01-07 4 views
6

Wenn Jsoup auf bestimmte HTML-Typen (entweder komplex oder inkorrekt) stößt, wird möglicherweise schlecht formatierter HTML-Code ausgegeben. Ein Beispiel ist:Wie kann Jsoup wohlgeformtes XML ausgeben?

<html> 
<head> 
    <meta name="x" content="y is "bad" here"> 
</head> 
<body/> 
</html> 

wo die Anführungszeichen hätten entkommen sein sollen. Wenn Jsoup dies analysiert, gibt es Folgendes aus:

<html> 
<head> 
    <meta name="x" content="y is " bad"="" here"="" /> 
</head> 
<body></body> 
</html> 

die nicht konform HTML oder XML ist. Dies ist problematisch, da es beim nächsten Parser in der Kette fehlschlägt.

Gibt es eine Möglichkeit, sicherzustellen, dass Jsoup entweder eine Fehlermeldung ausgibt oder (wie HtmlTidy) wohlgeformtes XML ausgeben kann, selbst wenn es einige Informationen verloren hat (schließlich können wir jetzt nicht sicher sein, was richtig ist).

UPDATE: Der Code, der nicht ist:

@Test 
public void testJsoupParseMetaBad() { 
    String s = "<html><meta name=\"x\" content=\"y is \"bad\" here\"><body></html>"; 
    Document doc = Jsoup.parse(s); 
    String ss = doc.toString(); 
     Assert.assertEquals("<html> <head> <meta name=\"x\" content=\"y is \"" 
      +" bad\"=\"\" here\"=\"\" /> </head> <body></body> </html>", ss); 
} 

Ich verwende:

<dependency> 
     <groupId>org.jsoup</groupId> 
     <artifactId>jsoup</artifactId> 
     <version>1.7.2</version> 
    </dependency> 

Andere scheinen das gleiche Problem zu haben: JSoup - Quotations inside attributes Die Antwort gibt mir nicht helfen, Ich muss akzeptieren, was ich bekomme

+0

Da jSoup ein DOM-Parser ist es sollte das nicht tun. Das Rekonstruieren des HTML-Textes von einem DOM kann nicht zu der Ausgabe führen, die Sie anzeigen (IMHO). Würden Sie ein Codebeispiel hinzufügen, das dieses Verhalten zeigt? – Tomalak

+1

Ich stimme Ihrer Logik zu. Ich habe den Code hinzugefügt, den ich verwende, um den "HTML" oben zu analysieren. –

+0

@Tomalak Wo heißt es, dass jSoup ein DOM-Parser ist (im Sinne von w3c)? Die lokalen Namen scheinen identisch zu sein, aber das ist alles. Nach einem kurzen Blick auf die Quelle erfordert die Korrektur wahrscheinlich Codeänderungen. –

Antwort

1

Das Problem ist, wenn Sie analysieren, weil jsoup 3 Attribute erstellt:

content="y is "bad" here" 

und der Name der Attribute enthält Zitat "Zeichen. Jsoup entzieht den Attributen Werte, nicht jedoch deren Namen.

Da Sie das HTML-Dokument aus einer Zeichenfolge erstellen, können Sie den Fehler bei der Parser-Phase erhalten. Es gibt eine Methode, die ein org.jsoup.parser.Parser als Argument erhält. Die Standardanalysemethode verfolgt keine Fehler.

String s = "<html><meta name=\"x\" content=\"y is \"bad\" here\"><body></html>"; 
    Parser parser = Parser.htmlParser(); // or Parser.xmlParser 
    parser.setTrackErrors(100); 
    Document doc = Jsoup.parse(s, "", parser); 
    System.out.println(parser.getErrors()); 

Output:

[37: Unexpected Zeichen 'a' in Eingabezustand [AfterAttributeValue_quoted], 40: Unexpected Zeichen '' in Eingabezustand [Attributename], 46: Unexpected Zeichen '>' in Eingang Zustand [Attribute]]

Falls Sie nicht möchten, dass die Parse ändern und wollen nur eine gültige Ausgabe erhalten Sie nur ungültige Attribute entfernen konnte:

public static void fixIt(Document doc) { 
    Elements els = doc.getAllElements(); 
    for(Element el:els){ 
     Attributes attributes = el.attributes(); 
     Set<String> remove = new HashSet<>(); 
     for(Attribute a:attributes){ 
      if(isForbidden(a.getKey())){ 
       remove.add(a.getKey()); 
      } 
     } 

     for(String k:remove){ 
      el.removeAttr(k); 
     } 
    } 
} 

public static boolean isForbidden(String el) { 
    return el.contains("\""); //TODO 
} 
Verwandte Themen