Java - Читать XML и оставить все объекты в покое - PullRequest
1 голос
/ 12 сентября 2011

Я хочу читать файлы XHTML, используя SAX или StAX, что бы ни работало лучше всего.Но я не хочу, чтобы сущности были разрешены, заменены или что-то в этом роде.В идеале они должны просто оставаться такими, как есть.Я не хочу использовать DTD.

Вот пример (исполняемый файл с использованием Scala 2.8.x):

import javax.xml.stream._
import javax.xml.stream.events._
import java.io._

println("StAX Test - "+args(0)+"\n")
val factory = XMLInputFactory.newInstance
factory.setProperty(XMLInputFactory.SUPPORT_DTD, false)
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false)

println("------")
val xer = factory.createXMLEventReader(new FileReader(args(0)))
val entities = new collection.mutable.ArrayBuffer[String]
while (xer.hasNext) {
    val event = xer.nextEvent
    if (event.isCharacters) {
        print(event.asCharacters.getData)
    } else if (event.getEventType == XMLStreamConstants.ENTITY_REFERENCE) {
        entities += event.asInstanceOf[EntityReference].getName
    }
}
println("------")
println("Entities: " + entities.mkString(", "))

Учитывая следующий файл xhtml ...

<html>
    <head>
        <title>StAX Test</title>
    </head>
    <body>
        <h1>Hallo StAX</h1>
        <p id="html">
            &lt;div class=&quot;header&quot;&gt;
        </p>
        <p id="stuff">
            &Uuml;berdies sollte das hier auch als Copyright sichtbar sein: &#169;
        </p>
        Das war's!
    </body>
</html>

... выполнение scala stax-test.scala stax-test.xhtml приведет к:

StAX Test - stax-test.xhtml

------


    StAX Test


    Hallo StAX

      <div class="header">


      berdies sollte das hier auch als Copyright sichtbar sein: ?

    Das war's!

------
Entities: Uuml

Таким образом, все объекты были заменены более или менее успешно.Что бы я ожидал и чего я хочу, так это:

StAX Test - stax-test.xhtml

------


    StAX Test


    Hallo StAX

      &lt;div class=&quot;header&quot;&gt;


      &Uuml;berdies sollte das hier auch als Copyright sichtbar sein: &#169;

    Das war's!

------
Entities: // well, or no entities above and instead:
// Entities: lt, quot, quot, gt, Uuml, #169

Возможно ли это вообще?Я хочу проанализировать XHTML, сделать некоторые изменения и затем снова вывести его как XHTML.Поэтому я действительно хочу, чтобы сущности оставались в результате.

Также я не понимаю, почему Uuml сообщается как событие EntityReference, а остальные нет.

Ответы [ 3 ]

2 голосов
/ 12 сентября 2011

Немного терминологии: &#x169; - это числовая ссылка на символ (не сущность), а &#auml; - это ссылка на сущность (не сущность).

Я не думаю, что какой-либо парсер XMLсообщит числовые ссылки на символы в приложение - они всегда будут расширены.Действительно, ваше приложение должно заботиться об этом не больше, чем о том, сколько пробелов имеется между атрибутами.

Что касается ссылок на сущности, низкоуровневые интерфейсы синтаксического анализа, такие как SAX, сообщат о существовании сущностиссылка - во всяком случае, она сообщает о них, когда они встречаются в контенте элемента, а не в контенте атрибута.О специальных событиях уведомляется только LexicalHandler, а не ContentHandler.

1 голос
/ 12 сентября 2011

Ответ на вопрос «почему Uuml сообщается как событие EntityReference, а остальные нет» заключается в том, что остальные определяются спецификацией XML, а &Uuml; относится к HTML 4.0 .

Поскольку ваша цель - написать модифицированный XHTML, может заставить принудительно сериализатор выдавать числовые ссылки на сущности, установив для "encoding" значение "US-ASCII" и / или "method" в "HTML". Спецификация XSLT (которая лежит в основе сериализаторов Java XML) говорит, что сериализатор «может выводить символ, используя ссылку на символьную сущность», когда метод html. Установка кодировки в ASCII может заставить его использовать числовые объекты, если именованные объекты не поддерживаются.

0 голосов
/ 12 сентября 2011

В Java я бы использовал регулярное выражение.

public static void main(String... args) throws IOException {
  BufferedReader buf = new BufferedReader(new FileReader(args[0]));
  Pattern entity = Pattern.compile("&([^;]+);");
  Set<String> entities = new LinkedHashSet<String>();
  for (String line; (line = buf.readLine()) != null; ) {
    Matcher m = entity.matcher(line);
    while (m.find())
      entities.add(m.group(1));
  }
  buf.close();
  System.out.println("Entities: " + entities);
}

печать

Entities: [lt, quot, gt, Uuml, #169]
...