如何使用StaxEventItemWriter rootElementAttribs创建名称空间

时间:2018-12-27 17:36:21

标签: spring-batch

我正在使用Spring Batch StaxEventItemWriter和Jaxb2Marshaller创建XML文件;最终文件包括以下名称空间:

<?xml version="1.0" encoding="UTF-8"?>
<product-lists 
xmlns="http://www.demandware.com/xml/impex/productlist/2009-10-28">
<product-list list-id="14d3a4eb97570219f2bd26525e">
<owner customer-no="00002004">
<email>c@j9.com</email>
</owner>
<type>wish_list</type>
<public>false</public>
</product-list>
</product-lists>

使用StaxEventItemWriter创建名称空间属性时,出现以下错误:

Caused by: javax.xml.stream.XMLStreamException: xmlns has been already bound to . Rebinding it to http://www.demandware.com/xml/impex/productlist/2009-10-28 is an error
    at com.sun.xml.internal.stream.writers.XMLStreamWriterImpl.writeDefaultNamespace(XMLStreamWriterImpl.java:786)
    at com.sun.xml.internal.stream.writers.XMLStreamWriterImpl.writeNamespace(XMLStreamWriterImpl.java:1003)
    at com.sun.xml.internal.stream.writers.XMLEventWriterImpl.add(XMLEventWriterImpl.java:127)

项目编写者的代码:

@Bean(destroyMethod = "")
public ItemWriter<ProductList> xmlWriter() 
   StaxEventItemWriter<ProductList> xmlFileWriter = new StaxEventItemWriter<>();
   HashMap<String, String> rootElementAttribs = new HashMap<String, String>();
   String exportFilePath = "./XXX_List_XXX_" + FeedBatchUtil.getCurrentTimeStamp().replace(":", "").replace(".", "_") + ".xml";
   /* Doen not Work*/
   rootElementAttribs.put("xmlns", "http://www.demandware.com/xml/impex/productlist/2009-10-28");
   /*Works*/
   //rootElementAttribs.put("xmlns:ns1", "http://www.demandware.com/xml/impex/productlist/2009-10-28");
   xmlFileWriter.setResource(new FileSystemResource(exportFilePath));
   xmlFileWriter.setRootTagName("product-lists");
   xmlFileWriter.setRootElementAttributes(rootElementAttribs);
   Jaxb2Marshaller empMarshaller = new Jaxb2Marshaller();
   empMarshaller.setClassesToBeBound(ProductList.class);
   xmlFileWriter.setShouldDeleteIfEmpty(true);
   xmlFileWriter.setMarshaller(empMarshaller);
   return xmlFileWriter;
}

1 个答案:

答案 0 :(得分:0)

  

我希望名称空间值如下<product-lists xmlns="demandware.com/xml/impex/productlist/2009-10-28">

这里是一个例子:

StaxEventItemWriter<ProductList> staxEventItemWriter = new StaxEventItemWriter<>();
staxEventItemWriter.setResource(new FileSystemResource("test.xml"));
HashMap<String, String> rootElementAttribs = new HashMap<String, String>();
rootElementAttribs.put("xmlns", "demandware.com/xml/impex/productlist/2009-10-28");
staxEventItemWriter.setRootTagName("product-lists");
staxEventItemWriter.setRootElementAttributes(rootElementAttribs);
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setClassesToBeBound(ProductList.class);
staxEventItemWriter.setMarshaller(marshaller);
staxEventItemWriter.afterPropertiesSet();

staxEventItemWriter.open(new ExecutionContext());
staxEventItemWriter.write(Arrays.asList(new ProductList()));
staxEventItemWriter.close();

ProductList的定义如下:

@XmlRootElement
private static class ProductList {
    // TODO add your fields as required
}

上一个示例生成一个test.xml文件,该文件具有您要查找的名称空间:

<?xml version='1.0' encoding='UTF-8'?>
<product-lists xmlns="demandware.com/xml/impex/productlist/2009-10-28">
    <productList/>
</product-lists>

希望这会有所帮助。