Я сгенерировал свои классы JAXB, используя xjc , но используемый мной SOAP WebService вынуждает меня следовать некоторым правилам, например, не использовать префикс пространства имен.
Это неверно:
<envEvento versao="1.00" xmlns="http://www.portalfiscal.inf.br/nfe" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#">
<idLote>123</idLote>
<evento>
<ns2:Signature/>
</evento>
</envEvento>
Это действительно:
<envEvento versao="1.00" xmlns="http://www.portalfiscal.inf.br/nfe">
<idLote>123</idLote>
<evento>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"/>
</evento>
</envEvento>
Как указывалось, JAXB помещает объявление пространства имен в корневой элемент.
Чтобы преодолеть это, первый подход, который я использую, состоит в том, чтобы избежать ненужных элементов в контексте.
Например, установить контекст маршаллера следующим образом:
JAXBContext.newInstance("path.to.package");
Может привести к тому, что JAXB сделает несколько ненужных объявлений пространств имен.
Иногда я могу получить раздражающий xmlns = "http://www.w3.org/2000/09/xmldsig#", просто установив контекст с необходимым корневым элементом:
JAXBContext.newInstance(MyRootElement.class);
Второй подход, который я использую, когда первого недостаточно, заключается в том, чтобы весь контекст использовал одно и то же пространство имен. Просто изменив нежелательное "http://www.w3.org/2000/09/xmldsig#", в каждом объявлении пространства имен (например, @XmlElement или @XSchema), на уникальное допустимое пространство имен (http://www.portalfiscal.inf.br/nfe)
Затем я просто создаю атрибут у нужного ребенка:
@XmlAttribute(name="xmlns")
String xmlns = "http://www.w3.org/2000/09/xmldsig#";
Теперь у меня есть объявление пространства имен вне корня, в правильном элементе, без использования префикса.