Допустимы ли фрагменты XML? - PullRequest
0 голосов
/ 11 марта 2009

Я хочу хранить некоторые фрагменты файла XML в отдельных файлах. Кажется, нет прямого способа сделать это: Чтение кусков не удается.

Я всегда получаю исключение "javax.xml.transform.TransformerException: org.xml.sax.SAXParseException: разметка в документе, следующем за корневым элементом, должна быть правильной."

Работает только тогда, когда есть только ОДИН «корневой» элемент (который не корневой элемент в обычном смысле).

Я понимаю, что XML с несколькими «корнями» не является правильно сформированным, но это следует рассматривать как кусок.

Пожалуйста, прежде чем предлагать какие-то обходные решения, скажите мне: Действительно ли куски XML действительны?

И если так, могут ли они считываться с использованием стандартного API JDK6?

Тестовый код:

String testChunk1 = "<e1>text</e1>";
String testChunk2 = "<e1>text</e1><e2>text</e2>";

// the following doesn't work with 'testChunk2'
StringReader sr = new StringReader(testChunk1);
StringWriter sw = new StringWriter();

TransformerFactory.newInstance().newTransformer().transform(
    new StreamSource(sr), new StreamResult(sw));

System.out.println(sw.toString());

Ответы [ 3 ]

2 голосов
/ 11 марта 2009

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

В мире .NET вы можете работать с фрагментами XML и, например, проверять их по схеме . Это говорит о том, что стоит искать подобную поддержку в библиотеках Java.

Если вы хотите преобразовать такие фрагменты с помощью XSLT, очень распространенный подход - поместить вокруг них элемент-обертку, который затем может выступать в качестве корня DOM.

1 голос
/ 11 марта 2009

Пожалуйста, прежде чем предлагать какие-то обходные решения, скажите: действительно ли куски XML действительны?

Не по своему праву.

Вы можете включить их (служащие в качестве внешних анализируемых сущностей XML) в другие документы с помощью таких методов, как ссылка на сущность, и вы можете анализировать их как фрагменты в существующих документах, используя такие методы, как parseWithContext (LS) DOM уровня 3 (который Java не дает, извините), но они не являются документами, поэтому любые интерфейсы, для которых требуется полный документ, не могут их принять.

Transformer требует полного документа в качестве входных данных, поскольку XSLT работает с полными документами и может быть сбит с толку чем-то, что содержит ноль или более одного корневого элемента. Обычный трюк - создать один корневой элемент, поместив документ в начальный и конечный теги, но это означает, что вы не можете иметь объявление XML (*), как упоминал Эдди.

(*: на самом деле оно называется «текстовым объявлением» при включении во внешнюю проанализированную сущность, но синтаксис точно такой же.)

1 голос
/ 11 марта 2009

Хотя я полагаю, что должен быть какой-то способ, возможно, глупый, делать то, что вы хотите, я не знаю ни одного способа сделать это. Как вы обнаруживаете, стандартные синтаксические анализаторы XML ожидают правильно сформированный XML.

Если вы хотите сохранить свой XML как несколько отдельных фрагментов в разных файлах, то, вероятно, лучший способ сделать это - создать собственный Reader или InputStream, который фактически (за кадром) читает все фрагменты в порядке и затем предоставьте этот упакованный Reader или InputStream преобразователю. Таким образом, синтаксический анализатор XML видит один XML-документ, но вы можете хранить его так, как хотите.

Если вы делаете что-то подобное, фрагменты (кроме самого первого) не могут начинаться со стандартного заголовка XML:

<?xml version="1.0" encoding="UTF-8" ?>
...