Видаліть 'standalone = "yes" з генерованого XML


82

Чи знаєте ви про налаштування JAXB для запобігання генеруванню автономного = "так" у отриманому XML?

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

7
Чому це проблема?
Корнел

@Kornel у моєму проекті, який, щоб звикнути до Tibco та WebMethod, призведе до помилки, оскільки автономне = так не розпізнається
aswzen

Відповіді:


62

Ця властивість:

marshaller.setProperty("com.sun.xml.bind.xmlDeclaration", false);

... можна використовувати, щоб не мати:

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

Однак я б не вважав цю найкращу практику.


2
Дякую, це саме те, що мені потрібно було. Я б погодився, що це найкраща практика включати рядок, але веб-служба, з якою я взаємодію, не очікує цього.
jgrowl

6
Добре, що він працює, але FWIW, служба не працює, якщо вона не може прийняти легальний xml, тому, мабуть, добре подати повідомлення про помилку.
StaxMan

4
Не працює з JAXB у JDK1.6. Дивіться відповідь so_mv для правильного рішення.
sverch

1
Що вибухає в польоті: виняток.
Ніколас Барбулеско,

1
@sversch: ви можете спробувати клас властивостей: "com.sun.xml.internal.bind.xmlHeaders"
baybora.oren

120

у JAXB, що є частиною JDK1.6

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

13
Це не дає очікуваного результату. Це видаляє весь рядок декларації XML. Я хочу просто видалити standaloneатрибут у декларації XML.
Ніколас Барбулеско,

Якщо ви задаєтеся питанням, чому це не працює для вас, як і я, тоді відповідь полягає в тому, що ефект залежить від того, якого маршала Апі ви використовуєте. Для маршала (Object, Outputstream) та маршала (Object, Writer) це працює, як пропонується тут. Для маршала (Об'єкт, Вузол) це не впливає. Інші наслідки api для маршала див. Тут у розділі Підтримувані властивості.
Лассе Самсон

60

Ви можете або використовувати

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

або

marshaller.setProperty("com.sun.xml.bind.xmlDeclaration", false)

вимкнути декларацію XML за замовчуванням, а потім додати власну декларацію XML,

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

від

marshaller.setProperty("com.sun.xml.bind.xmlHeaders",
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

до згенерованого xml, тим самим уникаючи автономної властивості = "yes" .


2
"SetProperty" з "xmlDeclaration" вибухає в польоті: виняток.
Ніколас Барбулеско,

2
Рядок "setProperty" із "xmlHeaders" теж не працює. PropertyException. Тож це не рішення.
Ніколас Барбулеско,

яку версію Java та jaxb ви використовуєте?
WarFox

@WarFox Команда setProperty з xmlHeaders не працює з jdk1.6.0_24 та JAXB версії 2.1
Брайан Ларсон,

3
Незалежно від java6 або java7 мені довелося додати 'internal', тобто marshaller.setProperty ("com.sun.xml.internal.bind.xmlHeaders", "<? Xml version = \" 1.0 \ "encoding = \" UTF-8 \ "?>");
Каольте

7

просто якщо хтось ще бореться з цією проблемою, ви можете розглянути можливість її використання

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);

щоб видалити всю декларацію XML і просто написати свій власний Stringна початку потоку / методу виводу


5

Якщо ви зробите документ залежним від DOCTYPE(наприклад, використовуєте іменовані сутності), то він перестане бути автономним, тому standalone="yes"не буде дозволено в декларації XML.

Однак автономний XML можна використовувати де завгодно, тоді як не автономний є проблематичним для аналізаторів XML, які не завантажують зовнішні.

Я не бачу, як ця декларація може бути проблемою, крім взаємодії з програмним забезпеченням, яке не підтримує XML, але якийсь жахливий суп із регулярними виразами.


1
Точно, будь-яка система обробки xml, яка нібито обмінюється в декларації xml, здається дуже підозрілою.
StaxMan

1
Яким чином воно відповідає на питання?
ᄂ ᄀ

Як можна зробити так, щоб документ залежав DOCTYPE?
Lii

3
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
jaxbMarshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");

Це працювало у мене з JDK1.7. standalone = \ "no \" можна видалити, щоб отримати лише решту частини xml


1
помилка: javax.xml.bind.PropertyException: name: com.sun.xml.internal.bind.xmlHeaders value: <? xml version = "1.0" encoding = "UTF-8"?>
aswzen

3

Якщо ви використовуєте лише пакет javax.xml за замовчуванням, ви можете встановити параметр JAXB_FRAGMENT в маршалері на "true" (це опускає інструкцію обробки xml за замовчуванням) і використовувати метод writeProcessingInstruction XMLStreamWriter, щоб вставити свій власний:

xmlStreamWriter.writeProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
jaxbMarshaller.setProperty( Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
jaxbMarshaller.marshal(object, xmlStreamWriter);
xmlStreamWriter.writeEndDocument();


1

У мене недостатньо висока "репутація", щоб мати "привілей" коментувати. ;-)

@Debasis, зверніть увагу, що вказане вами властивість:

"com.sun.xml.internal.bind.xmlHeaders"

має бути:

"com.sun.xml.bind.xmlHeaders" (without the "internal", which are not meant to be used by the public)

Якщо я використовую властивість " Internal ", як і ви, я отримую javax.xml.bind.PropertyException


1

Якщо ви отримуєте виняток із властивостей, додайте таку конфігурацію:

jaxbMarshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders",
              "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
jaxbMarshaller.setProperty("com.sun.xml.internal.bind.xmlDeclaration", Boolean.FALSE);
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);  

1

Я використовую Java 1.8 та JAXB 2.3.1

По-перше, обов’язково використовуйте java 1.8 у pom.xml

<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>

Потім у вихідному коді я використовував: (ключ був внутрішньою частиною)

// remove standalone=yes
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

0

просто спробуйте

private String marshaling2(Object object) throws JAXBException, XMLStreamException {
    JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
    StringWriter writer = new StringWriter();
    writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
    jaxbMarshaller.marshal(object, writer);
    return writer.toString();
  }

0

Якщо у вас є <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

але хочу цього: <?xml version="1.0" encoding="UTF-8"?>

Просто зробіть:

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.