2008-10-23 5 views
6

Ich versuche eine Datei zu lesen, um ein DOM Dokument zu erzeugen, aber die Datei hat Leerzeichen und Zeilenumbrüche und ich versuche sie zu ignorieren, aber ich konnte sie nicht t:Wie ignoriert man Whitespace beim Lesen einer Datei um ein XML DOM zu erzeugen

DocumentBuilderFactory docfactory=DocumentBuilderFactory.newInstance(); 
docfactory.setIgnoringElementContentWhitespace(true); 

ich in Javadoc sehen, die setIgnoringElementContentWhitespace Methode nur dann arbeitet, wenn die Validierung Flag aktiviert ist, aber ich habe nicht die DTD oder XML-Schema für das Dokument.

Was kann ich tun?

aktualisieren

Ich mag nicht die Idee vorstelle <! ELEMENT ... Erklärungen und ich versucht haben, die Lösung in der von Tomalak zeigte forum vorgeschlagen, aber es funktioniert nicht, ich habe benutze Java 1.6 in einer Linuxumgebung. Ich denke, wenn nicht mehr vorgeschlagen wird, ich werde ein paar Methoden machen zu ignorieren Leerzeichen Textknoten

Antwort

9

‚IgnoringElementContentWhitespace‘ geht es nicht um das Entfernen alle rein Leerzeichen Textknoten, nur Leerzeichen Knoten, deren Eltern im Schema beschrieben werden als mit ELEMENT-Inhalt - das heißt, sie enthalten nur andere Elemente und niemals Text.

Wenn Sie kein Schema (DTD oder XSD) verwenden, wird der Inhalt des Elements standardmäßig auf MIXED gesetzt, so dass dieser Parameter niemals wirksam wird. (Es sei denn, der Parser stellt eine nicht-standardmäßige DOM-Erweiterung zur Verfügung, um alle unbekannten Elemente als ELEMENT-Inhalt zu behandeln, was meines Wissens nach nicht für Java verfügbar ist.)

Sie könnten das Dokument auf dem Weg in die Parser, um die Schemainformationen einzubeziehen, z. B. indem Sie der Deklaration <! DOCTYPE ... [...]> <! ELEMENT ...> Deklarationen eine interne Teilmenge hinzufügen und anschließend den Parameter IgnoringElementContentWhitespace verwenden.

Oder, möglicherweise einfacher, Sie könnten nur die Whitespace-Knoten entweder in einem Post-Prozess oder wie sie kommen mit einem LSParserFilter.

+0

Ich muss schließlich Leerzeichen programmatisch ignorieren, wie Sie im las Absatz vorschlagen – Telcontar

5

Dies ist eine (wirklich) späte Antwort, aber hier ist, wie ich es gelöst habe. Ich schrieb meine eigene Implementierung einer NodeList Klasse. Es ignoriert einfach Textknoten, die leer sind. Code folgt:

private static class NdLst implements NodeList, Iterable<Node> { 

    private List<Node> nodes; 

    public NdLst(NodeList list) { 
     nodes = new ArrayList<Node>(); 
     for (int i = 0; i < list.getLength(); i++) { 
      if (!isWhitespaceNode(list.item(i))) { 
       nodes.add(list.item(i)); 
      } 
     } 
    } 

    @Override 
    public Node item(int index) { 
     return nodes.get(index); 
    } 

    @Override 
    public int getLength() { 
     return nodes.size(); 
    } 

    private static boolean isWhitespaceNode(Node n) { 
     if (n.getNodeType() == Node.TEXT_NODE) { 
      String val = n.getNodeValue(); 
      return val.trim().length() == 0; 
     } else { 
      return false; 
     } 
    } 

    @Override 
    public Iterator<Node> iterator() { 
     return nodes.iterator(); 
    } 
} 

Sie dann alle Ihre NodeList s in dieser Klasse wickeln und es werden alle Leerzeichen Knoten effektiv ignorieren. (Was ich als Textknoten mit getrimmtem Text der Länge 0 definiert.)

Es hat auch den zusätzlichen Vorteil, dass es in einer for-each-Schleife verwendet werden kann.

+0

Das ist nicht, wie es funktioniert ignoriert auch Leerzeichen ** Inhalt ** in realen Knoten! – Strinder

+0

@Strinder Ich weiß, dass Sie nicht zurückkommen können (tut mir leid), aber ich wollte Sie wissen lassen, dass ich einen "Knoten" ignorieren wollte, der nur Leerraum war. In meiner Anwendung würde es in meinem XML niemals einen sinnvollen Whitespace geben. – jjnguy

+0

Ich habe whitespaces aus einem einfachen Grund: Da ich Teile von XML teile, kann ich keine XSD bereitstellen - was bedeutet, dass ich nicht zwischen Raum BETWEEN Knoten und Raum als Inhalt innerhalb von Knoten unterscheiden kann! Allerdings ignoriere ich diese Knoten jetzt (mit dem Bewusstsein, dass die Unterschiede irgendwie "unvollständig" sind). – Strinder

2

Ich habe es funktioniert, indem Sie diese

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
     dbFactory.setIgnoringElementContentWhitespace(true); 
     dbFactory.setSchema(schema); 
     dbFactory.setNamespaceAware(true); 
NodeList nodeList = element.getElementsByTagNameNS("*", "associate"); 
0

Versuchen Sie folgendes:

private static Document prepareXML(String param) throws ParserConfigurationException, SAXException, IOException { 

     param = param.replaceAll(">\\s+<", "><").trim(); 
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
     factory.setIgnoringElementContentWhitespace(true); 
     DocumentBuilder builder = factory.newDocumentBuilder(); 
     InputSource in = new InputSource(new StringReader(param)); 
     return builder.parse(in); 

    }