2012-02-15 2 views
10

Я использую свойство JAXB_FRAGMENT для моего маршаллера для маршалирования на уровне WorkSet. Проблема в том, что когда я маршал, он каждый раз придает элементу WorkSet атрибут xmlns. Есть ли способ маршалировать, чтобы он не привязывал атрибут xmlns? Вот как выглядит мой XML.JAXB Фрагмент маршала без пространства имен

<Import> 
     <WorkSets> 
      <WorkSet xmlns="http://www.namespace.com"> 
       <Work> 
       <Work> 
       ... 
       .. 
       ... 
      </WorkSet> 
      <WorkSet xmlns="http://www.namespace.com"> 
       <Work> 
       <Work> 
       ... 
      </WorkSet> 
     </WorkSets> 
    </Import> 

Вот код, я с помощью создания выше:

FileOutputStream fos = new FileOutputStream("import.xml"); 
XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(fos); 

JAXBContext jc = JAXBContext.newInstance(WorkSet.class); 
Marshaller m = jc.createMarshaler(); 
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 

writer.writeStartDocument(); 
writer.writeStartElement("Import"); 
writer.writeAttribute("xmlns","http://www.namespace.com"); 
writer.writeStartElement("WorkSets"); 

while(hasWorkSet){ 
m.marshal(workSet, writer) 
} 
writer.writeEndDocument(); 
writer.close(); 
+0

Вы хотите иметь объявление пространства имен выше в документе, или вы не хотите, чтобы пространство имен было объявлено вообще? –

+0

@BlaiseDoughan Я пишу теги Import и WorkSets вручную через XMLStreamWriter, поэтому я также устанавливаю их атрибуты вручную. Я использую JAXB для маршалирования коллекции экземпляров WorkSet, которая работает нормально, я просто не хочу, чтобы атрибут xmlns привязывался к каждому. Он не помещал атрибуты xmlns в WorkSet, когда я использовал JAXB для совместного использования всего экземпляра XML (Import, Worksets, WorkSet, Work ..). Это началось только тогда, когда я переключил JAXB_FRAGMENT на маршалирование только WorkSet. – TyC

+0

@BlaiseDoughan Я просматривал API JAXB и до сих пор не вижу, что заставляет пространство имен помещаться в элемент WorkSet. – TyC

ответ

8

Предполагая, что вы хотите, пространство имен по умолчанию для вашего документа, чтобы быть http://www.namespace.com, вы можете сделать следующее:

Demo

XMLStreamWriter.setDefaultNamespace(String) и XMLStreamWriter.writeNamespace(String, String) методы будут использоваться для установки и записи пространства имен по умолчанию для XML-документа.

package forum9297872; 

import javax.xml.bind.*; 
import javax.xml.stream.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(System.out); 
     writer.setDefaultNamespace("http://www.namespace.com"); 

     JAXBContext jc = JAXBContext.newInstance(WorkSet.class); 
     Marshaller m = jc.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 

     writer.writeStartDocument(); 
     writer.writeStartElement("http://www.namespace.com", "Import"); 
     writer.writeNamespace("", "http://www.namespace.com"); 
     writer.writeStartElement("WorkSets"); 

     m.marshal(new WorkSet(), writer); 
     m.marshal(new WorkSet(), writer); 

     writer.writeEndDocument(); 
     writer.close(); 
    } 

} 

рабочий набор

Мое предположение, что вы указали информацию о пространстве имен в вашей модели JAXB.

package forum9297872; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name="WorkSet", namespace="http://www.namespace.com") 
public class WorkSet { 

} 

Выход

Ниже показан результат запуска демо-код:

<?xml version="1.0" ?><Import xmlns="http://www.namespace.com"><WorkSets><WorkSet></WorkSet><WorkSet></WorkSet></WorkSets></Import> 
+0

Это сработало, но я понятия не имею, почему. В классе WorkSet не указано имя. Вот тег XmlRootElement, прикрепленный к классу. @XmlRootElement (name = "WorkSet"). – TyC

+0

Есть ли класс 'package-info' в том же пакете, что и класс' WorkSet'? –

+0

Да. Он содержит следующее: @ javax.xml.bind.annotation.XmlSchema (namespace = "http://www.itron.com/nVanta", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) – TyC

1

Есть три обходные пути для этого.

1) Создайте аннотированные объекты JAXB для контейнера ваших рабочих. Добавьте рабочих к этому объекту, а затем маршалите все это.

2) Следуйте первому примеру в 101 ways to marshal objects with JAXB и используйте DocumentBuilderFactory с пространством имен.

3) Предполагая, что объект jaxb находится в пакете, который никогда не должен иметь квалифицированных пространств имен, вы можете добавить в аннотацию пакета следующее: (обратите внимание: прошло некоторое время с тех пор, как я сделал это, и я не тестировал этот код)

@XmlSchema(namespace = "", elementFormDefault = XmlNsForm.UNQUALIFIED) 
package example; 
0

Еще один пример:

try { 
     JAXBContext customerInformationRequestContext = JAXBContext.newInstance(CustomerInformationRequest.class); 
     Unmarshaller unmarshaller = customerInformationRequestContext.createUnmarshaller(); 
     StringReader stringReader = new StringReader(requestPayload); 
     XMLInputFactory xif = XMLInputFactory.newFactory(); 
     XMLStreamReader xsr = xif.createXMLStreamReader(stringReader); 
     XMLStreamReaderWrapper reader = new XMLStreamReaderWrapper(xsr); 
     CustomerInformationRequest customerInformationRequest = (CustomerInformationRequest) unmarshaller.unmarshal(reader); 
     CustomerInformationResponse customerInformationResponse = customerLookup(customerInformationRequest, sessionTransaction); 
     JAXBContext customerInformationResponseContext = JAXBContext.newInstance(CustomerInformationResponse.class); 
     Marshaller marshaller = customerInformationResponseContext.createMarshaller(); 
     StringWriter stringWriter = new StringWriter(); 
     XMLOutputFactory xof = XMLOutputFactory.newFactory(); 
     XMLStreamWriter xsw = xof.createXMLStreamWriter(stringWriter); 
     xsw = new XMLStreamWriterWrapper(xsw); 
     marshaller.marshal(customerInformationResponse, xsw); 
     String responsePayload = stringWriter.toString(); 
     return responsePayload; 
    } catch (Exception e) { 
     log.debug("The payload could not be unmarshalled.", e); 
     return null; 
    } 
Смежные вопросы