Получить текст замены XML-сущности из DOM в Xerces - PullRequest
3 голосов
/ 24 мая 2011

Javadoc для org.w3c.dom.Entity состояний:

XML не требует, чтобы не проверяющий процессор XML считывал и обрабатывал объявления сущностей, сделанные во внешнем подмножестве или объявленные в сущностях параметров. Это означает, что проанализированные объекты, объявленные во внешнем подмножестве, не должны расширяться некоторыми классами приложений, и что текст замены объекта может быть недоступен. Когда текст замены доступен, дочерний список соответствующего узла сущности представляет структуру этого значения замены. В противном случае дочерний список пуст.

Хотя это не относится к объявлениям сущностей, сделанным во внутреннем подмножестве, обязательно должна быть какая-то конфигурация синтаксического анализатора, которая будет считывать и обрабатывать объявления сущностей в любом подмножестве? Действительно, мое чтение документации предполагает, что это по умолчанию.

В любом случае я проверил следующий подход (используя Xerces) к сущностям, которые были объявлены во внутреннем подмножестве (как показано), а также во внешнем подмножестве, но foo.hasChildNodes() возвращает false (и foo.getChildNodes() возвращает foo!) В каждом случае:

// some trivial example XML
String xml = "<!DOCTYPE example [ <!ENTITY foo 'bar'> ]>\n<example/>";
InputStream is = new ByteArrayInputStream(xml.getBytes());

// parse
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DocumentType docType = builder.parse(is).getDoctype();

// retrieve the entity - works fine
Entity foo = (Entity) docType.getEntities().getNamedItem("foo");

// now how to get the entity's replacement text?

Без сомнения, я упускаю что-то довольно очевидное; благодарен за ваши мысли.


EDIT

Из ответов до сих пор видно, что моя реализация Xerces работает неправильно. Я постараюсь обновить все библиотеки Xerces до последних версий и, если это решит мою проблему, я закрою этот вопрос. Большое спасибо.


UPDATE

Обновление Xerces действительно решило проблему при условии, что ссылка на сущность находится внутри документа; если это не так, то узел все еще не имеет дочерних элементов. Мне не совсем понятно, почему это так. Благодарен, если кто-то может объяснить, что происходит и / или указать мне, как я могу форсировать создание дочерних узлов без явной ссылки на каждую сущность из документа.

Ответы [ 4 ]

1 голос
/ 25 мая 2011

Я думаю, вы можете ошибаться, как работает текст замены.Основываясь на некотором прочтении (http://www.javacommerce.com/displaypage.jsp?name=entities.sql&id=18238),, мне кажется, что текст замены работает как переменная. Итак, в приведенном выше примере вы никогда не ссылаетесь на сущность &foo;. Если вы запустите приведенный ниже пример кода, вы увидитето, что происходит, это то, что &foo; заменяется строкой bar:

// some trivial example XML
String xml = "<!DOCTYPE example [ <!ENTITY foo 'bar'> ]><example><foo>&foo;</foo></example>";
InputStream is = new ByteArrayInputStream(xml.getBytes());

// parse
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(is);
DocumentType docType = doc.getDoctype();

// retrieve the entity - works fine
Entity foo = (Entity) docType.getEntities().getNamedItem("foo");
for(int i = 0; i < foo.getChildNodes().getLength(); i++) {
  System.out.println(foo.getChildNodes().item(i));
}

То, что вы видите напечатанным, это [#text: bar], который является заменой текста в XML.

0 голосов
/ 26 мая 2011

Я спросил в списке рассылки Xerces-J Users о несуществовании дочерних узлов, на которые нет ссылок на сущности в документе; там Михаил Главассевич услужливо указал мне на старый пост Энди Кларка , объясняющий следующее:

К сожалению (для вас) это особенность. И это было реализовано таким образом, в основном из соображений производительности. Если сущность никогда не упоминается в документе, то нам никогда не придется тратить время читая это. Если внешняя сущность огромна, но на нее никогда не ссылаются, мы не тратим время и память.

Кроме того, существует более глубокая проблема в отношении пространств имен. DOM не могу даже помочь. Я объясню ...

Возьмите следующий документ и внешнюю сущность:

  <!-- entity.ent -->
  <hello/>

  <!-- document.xml -->
  <!DOCTYPE root [
  <!ENTITY entity SYSTEM 'entity.ent'>
  ]>
  <root>
    <sub xmlns='foo'> &entity; </sub>
    <sub xmlns='bar'> &entity; </sub>
  </root>

Обратите внимание, что пространство имен по умолчанию отличается в каждой точке где на объект ссылаются. Это означает, что элемент будет связан с различными пространствами имен. Так что оба экземпляры одного и того же объекта на самом деле разные элементы!

В этой ситуации, что должен делать узел Entity в типе DOM return: дети в пространстве имен "foo" или дети в "баре" Пространство имен?

Короче говоря, это сложная проблема.

Возможно, вам лучше всего прочитать фрагмент документа себя, когда вы ищете узел сущности, и он не имеет дети. Xerces имеет сканер фрагментов документов в пакет, который будет полезен для этой цели. Вы должны были бы написать код, который создает дочерние элементы для фрагмента документа DOM из методов XNI, хотя. Но это не сложно сделать. Я могу укажи на пример, если он тебе нужен.

0 голосов
/ 25 мая 2011

Я не знаю, почему foo.getChildNodes() не работает, но я обнаружил следующее. Если объект используется (указан) в документе,

<!DOCTYPE example [<!ENTITY foo 'bar'>]>\n<example>&foo;</example> * * 1005

тогда текст замены доступен через

foo.getTextContent()

0 голосов
/ 25 мая 2011

Возможно, я ошибаюсь, но я думаю, что узлы сущностей хранят замещающий текст как текстовое значение, а не как набор узлов; это потому, что сущности фактически не анализируются полностью при синтаксическом анализе определений сущностей: это главным образом потому, что обработчик DTD является своего рода предварительным процессором, который происходит перед фактическим процессом синтаксического анализа. Поэтому проверьте текстовое значение узла сущности вместо списка дочерних узлов.

...