2008-10-23 8 views
6

Próbuję odczytać plik, aby utworzyć dokument DOM, ale plik zawiera białe znaki i staram się je ignorować, ale nie mogłem tego zrobić. T:Jak zignorować białe znaki podczas odczytu pliku w celu wygenerowania XML DOM

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

widzę w Javadoc że metoda setIgnoringElementContentWhitespace działa tylko wtedy, gdy flaga walidacji jest włączona, ale nie mam DTD lub XML Schema dla dokumentu.

Co mogę zrobić?

Aktualizacja

nie podoba mi się pomysł wprowadzenia siebie <! ELEMENT ... deklaracje i próbowałem rozwiązanie zaproponowane w forum wskazanym przez Tomalak, ale to nie działa, mam używał java 1.6 w środowisku linuxowym. Myślę, że gdyby zaproponowano więcej nie będę robić kilka metod ignorowanie białych znaków węzłów tekstowych

Odpowiedz

9

„IgnoringElementContentWhitespace” nie chodzi o usunięcie wszystkie pure-białych znaków węzłów tekstowych, tylko odstępu węzłów, których rodzice są opisane w schemacie jako posiadające Treści ELEMENT - to znaczy zawierają tylko inne elementy i nigdy nie tekst.

Jeśli nie używasz schematu (DTD lub XSD) w użyciu, zawartość elementu jest domyślnie ustawiona na MIESZANE, więc ten parametr nigdy nie będzie miał żadnego efektu. (O ile parser nie dostarcza niestandardowego rozszerzenia DOM do traktowania wszystkich nieznanych elementów jako zawierających zawartość ELEMENT, o ile mi wiadomo, te, które są dostępne dla języka Java, nie.)

Możesz zhakować dokument po drodze do analizator składni do uwzględnienia informacji o schemacie, na przykład poprzez dodanie wewnętrznego podzestawu do deklaracji <! DOCTYPE ... [...]> zawierającej deklaracje <! ELEMENT ...>, a następnie użyj parametru IgnoringElementContentWhitespace.

Albo, być może łatwiejsze, można po prostu rozebrać węzły białych spacji, albo w postprocesie, albo przy użyciu LSParserFilter.

+0

I wreszcie ignorować spacje programowo, jak sugerujesz w las ust – Telcontar

5

To jest (naprawdę) spóźniona odpowiedź, ale oto jak ją rozwiązałem. Napisałem własną implementację klasy NodeList. Po prostu ignoruje puste węzły tekstowe. Kod następująco:

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(); 
    } 
} 

Następnie owinąć wszystkich NodeList s w tej klasie i będzie skutecznie ignorować wszystkie węzły białymi znakami. (Które zdefiniowałem jako Węzły Tekstowe z przyciętym tekstem o długości 0).

Ma także dodatkową zaletę, że może być używany w pętli for-each.

+0

To nie działa jak to również ignoruje białą ** treść ** w prawdziwych węzłach! – Strinder

+0

@ Strinder Wiem, że nie możesz się wypowiedzieć (przepraszam za to), ale chciałem poinformować, że zamierzałem zignorować każdy "węzeł", który był tylko białą przestrzenią. W mojej aplikacji nigdy nie byłoby znaczących białych znaków w moim xml. – jjnguy

+0

Mam białe spacje z prostego powodu: od I diff części XML nie mogę zapewnić XSD - co oznacza, że ​​nie można różnicować między przestrzeń między węzłami i przestrzeni jako zawartość wewnątrz węzłów! Jednak teraz ignoruję te węzły (ze świadomością, że różnica jest w jakiś sposób "niekompletna"). – Strinder

2

Zrobiłem to działa wykonując tę ​​

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

Spróbuj tego:

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); 

    }