XMLOutputStream, восстановление пространств имен и атрибутов без пространств имен - PullRequest
1 голос
/ 18 июня 2010

Простое задание: написать элементу два атрибута:

String nsURI = "http://example.com/";
XMLOutputFactory outF = XMLOutputFactory.newFactory();
outF.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
XMLStreamWriter out = outF.createXMLStreamWriter(System.out);
out.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, "element", nsURI);
out.writeAttribute("attribute", "value");
out.writeAttribute("attribute2", "value");
out.writeEndElement();
out.close();

Ответ Вудстокса:

<element xmlns="http://example.com/" attribute="value" attribute2="value"></element>

Ответ JDK 6:

<zdef-1905523464:element xmlns="" xmlns:zdef-1905523464="http://example.com/" attribute="value" attribute2="value"></zdef-1905523464:element>

Что ?!

Далее, если мы добавим префикс к элементу:

out.writeStartElement("ns", "element", nsURI);

JDK 6 больше не будет пытаться создать xmlns = "":

<ns:element xmlns:ns="http://example.com/" attribute="value" attribute2="value"></ns:element>

И если мыотбросить атрибут (т.е. иметь только один) это нормально.

Я вполне уверен, что это ошибка в JDK 6. Я прав?И может ли кто-нибудь предложить работу, которая будет радовать обе библиотеки (и любые другие)?Я не хочу требовать Вудстокс, если смогу помочь.

Ответы [ 2 ]

2 голосов
/ 18 июня 2010

Я думаю, вы должны указать XMLStreamWriter, что такое пространство имен по умолчанию, а затем использовать его при добавлении элементов:

String nsURI = "http://example.com/";
XMLOutputFactory outF = XMLOutputFactory.newFactory();
outF.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
XMLStreamWriter out = outF.createXMLStreamWriter(System.out);
out.setDefaultNamespace(nsURI);
out.writeStartElement(nsURI, "element");
out.writeAttribute("attribute", "value");
out.writeAttribute("attribute2", "value");
out.writeEndElement();
out.close();

Приведенный выше код дает мне такой вывод:

<element xmlns="http://example.com/" 
    attribute="value" attribute2="value"></element>

с версией Java "1.6.0_20"

1 голос
/ 11 августа 2010

Мое предложение состояло бы в том, чтобы никогда не полагаться на версию writeAttribute () с двумя аргументами, поскольку определение того, что именно должно быть выведено, неясно: должно ли оно использовать пространство имен "" (также называемое "без пространства имен") или что-то еще текущее пространство имен по умолчанию? Это особенно запутанно, поскольку согласно спецификации XML атрибуты никогда не используют пространство имен по умолчанию (только явные). Таким образом, возможно, все выраженное поведение может рассматриваться как потенциально правильное; но, очевидно, они не могут все быть. Просто Stax API неправильно определяет (AFAIK), каким должен быть реальный ответ (а это плохо).

Итак: просто укажите пространство имен, которое должен использовать атрибут ("" или null, оба работают для "без пространства имен"), и все должно работать лучше.

Проблема с версией JDK, насколько мне известно, заключается в том, что некоторые версии предполагали, что атрибуты действительно использовали пространство имен по умолчанию; и именно поэтому этот фальшивый 'xmlns = ""' был добавлен. Это не нужно.

...