Удалите "standalone =" yes "" из сгенерированного XML.

82

Знаете ли вы о настройке JAXB, предотвращающей создание standalone = "yes" в итоговом XML?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
Йохан Пелгрим
источник
7
Почему это проблема?
Kornel
@Kornel в моем проекте, что для использования с Tibco и WebMethod он будет генерировать ошибку, потому что standalone = yes не распознается
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 08
4
Не работает с JAXB в JDK1.6. См. Ответ so_mv для правильного решения.
sversch
1
Взрывается в полете: исключение.
Николас Барбулеско
1
@sversch: вы можете попробовать класс свойств: "com.sun.xml.internal.bind.xmlHeaders"
baybora.oren
120

в JAXB, который является частью JDK1.6

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
so_mv
источник
13
Это не дает ожидаемого результата. Это удаляет всю строку объявления XML. Я хочу просто удалить standaloneатрибут в объявлении XML.
Николас Барбулеско
Если вам интересно, почему это не работает для вас, как и я, то ответ таков: эффект зависит от того, какой маршал-api вы используете. Для маршала (Object, Outputstream) и marshal (Object, Writer) это работает, как предлагается здесь. Для маршала (Объект, Узел) это не действует. Остальные последствия для marshal 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, избегая, таким образом, свойства standalone = "yes" .

WarFox
источник
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 \ "?>");
Caoilte
7

просто если кто-то все еще борется с этой проблемой, вы можете рассмотреть возможность использования

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

чтобы удалить все объявления XML и просто написать свое собственное Stringв начале потока / метода вывода

Benez
источник
5

Если вы сделаете документ зависимым от DOCTYPE(например, используете именованные сущности), он перестанет быть автономным, поэтому standalone="yes"он не будет разрешен в декларации XML.

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

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

Корнель
источник
1
Собственно, любая якобы система обработки xml, которая блокирует объявление xml, кажется очень подозрительной.
StaxMan 08
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: имя: com.sun.xml.internal.bind.xmlHeaders значение: <? 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();
Эддо
источник
2

Вы можете использовать: marshaller.setProperty ("jaxb.fragment", Boolean.TRUE);

У меня работает на Java 8

Уильям Фуншал Перейра
источник
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)

Если я использую "внутреннее" свойство, как вы, я получаю исключение 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\"?>");
Запеченный внутри
источник