【问题标题】:xmlns has been already bound to . Rebinding it to http://entreprise.uk/ns is an errorxmlns 已经绑定到 .将其重新绑定到 http://entreprise.uk/ns 是一个错误
【发布时间】:2021-10-21 23:12:26
【问题描述】:

我正在使用 Spring Batch 生成 xml 文件。

我的作者长这样:

Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setClassesToBeBound(Person.class);

StaxEventItemWriter<Person> itemWriter = new StaxEventItemWriter<>();
itemWriter.setRootTagName("Persons");
itemWriter.setMarshaller(marshaller);
itemWriter.setRootElementAttributes(new HashMap<String, String>() {{
        put("xmlns", "http://entreprise.uk/ns");
}});
itemWriter.setResource(new FileSystemResource(Paths.get("personOutput.xml").toFile()));
itemWriter.afterPropertiesSet();

return itemWriter;

还有人物类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Person")
public class Person {
  //...
}

当我运行批处理时出现此错误:

原因:javax.xml.stream.XMLStreamException: xmlns 已经绑定到 .将其重新绑定到http://entreprise.uk/ns 是一个错误

有人知道怎么解决吗?我需要在根元素处查看 xmlns 属性,例如:

<?xml version="1.0" encoding="UTF-8"?>
<Persons xmlns="http://entreprise.uk/ns">
    <person>...</person>
</Persons>

我正在使用spring-boot-starter-batch:2.3.5.RELEASE

【问题讨论】:

标签: java spring spring-boot jaxb spring-batch


【解决方案1】:

要在根级别添加命名空间,您必须在配置中修改 rootTagName。

rootTagName("{http://entreprise.uk/ns}Persons")

希望这能解决您的问题。

【讨论】:

    【解决方案2】:

    有两种方法可以解决这个问题:

    方法一 使用 package-info 文件:

    XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <Persons xmlns="http://entreprise.uk/ns">
        <person>
            <firstName>Batman</firstName>
        </person>
    </Persons>
    

    包信息.java:

    @XmlSchema(
            elementFormDefault = XmlNsForm.QUALIFIED,
            namespace = "http://entreprise.uk/ns",
            xmlns = {@XmlNs(prefix = "", namespaceURI = "http://entreprise.uk/ns")})
    package stackover;
    
    import jakarta.xml.bind.annotation.XmlNs;
    import jakarta.xml.bind.annotation.XmlNsForm;
    import jakarta.xml.bind.annotation.XmlSchema;
    

    人员:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "Persons")
    @Data
    public class Persons {
        private Person person;
    }
    

    人:

    @Data
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Person {
        private String firstName;
    }
    
    

    主要:

    
    public class Main {
        public static void main(String[] args) throws JAXBException, XMLStreamException {
            final InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("students.xml");
            final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
            final Unmarshaller unmarshaller = JAXBContext.newInstance(Persons.class).createUnmarshaller();
            final Persons persons = unmarshaller.unmarshal(xmlStreamReader, Persons.class).getValue();
            System.out.println(persons.toString());
    
            Marshaller marshaller = JAXBContext.newInstance(Persons.class).createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            marshaller.marshal(persons, System.out);
        }
    }
    

    输出:

    Persons(person=Person(firstName=Batman))
    <Persons xmlns="http://entreprise.uk/ns">
       <person>
          <firstName>Batman</firstName>
       </person>
    </Persons>
    

    方法二 使用 XML 的命名空间 URI 前缀并添加到根类:

    XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <Persons xmlns:ns0="http://entreprise.uk/ns">
        <person>
            <firstName>Batman</firstName>
        </person>
    </Persons>
    

    人员:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "Persons", namespace = "http://entreprise.uk/ns")
    @Data
    public class Persons {
        private Person person;
    }
    

    人:

    @Data
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Person {
        private String firstName;
    }
    
    

    主要:

    public class Main {
        public static void main(String[] args) throws JAXBException, XMLStreamException {
            final InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("students.xml");
            final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
            final Unmarshaller unmarshaller = JAXBContext.newInstance(Persons.class).createUnmarshaller();
            final Persons persons = unmarshaller.unmarshal(xmlStreamReader, Persons.class).getValue();
            System.out.println(persons.toString());
    
            Marshaller marshaller = JAXBContext.newInstance(Persons.class).createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            marshaller.marshal(persons, System.out);
        }
    }
    

    输出:

    Persons(person=Person(firstName=Batman))
    <ns0:Persons xmlns:ns0="http://entreprise.uk/ns">
       <person>
          <firstName>Batman</firstName>
       </person>
    </ns0:Persons>
    

    【讨论】:

      【解决方案3】:

      我个人会使用一个名为 Persons 的容器类,它有一个 Person 数组/列表。

      @XmlRootElement(name = "Persons", namespace = "http://entreprise.uk/ns")
      @XmlAccessorType(XmlAccessType.FIELD)
      public class Persons {
      
        @XmlElement(name = "Person")
        private List<Person> persons;
      
        //...
      }
      

      这也应该消除您当前必须设置的一些配置的需要。

      【讨论】:

      • 对不起,它没有工作,setRootTagName 应该与Persons 一起使用。否则将使用root
      猜你喜欢
      • 2021-08-30
      • 2014-03-14
      • 1970-01-01
      • 1970-01-01
      • 2012-12-11
      • 1970-01-01
      • 2013-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多