当前位置: 首页 > 知识库问答 >
问题:

默认命名空间

岳京
2023-03-14

我需要使用默认命名空间创建/读取xml文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xmlBoo xmlns="http://www.example2.org/boo">
    <customer>
        <address>
            <street>Wall Street</street>
        </address>
        <id>1</id>
        <name>John</name>
    </customer>
    <someSpecificField>Specific data in Boo</ns2:someSpecificField>
</xmlBoo>

但我得到:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:xmlBoo xmlns:ns2="http://www.example2.org/boo">
    <ns2:customer>
        <address>
            <street>Wall Street</street>
        </address>
        <id>1</id>
        <name>John</name>
    </ns2:customer>
    <ns2:someSpecificField>Specific data in Boo</ns2:someSpecificField>
</ns2:xmlBoo>

我知道包级元数据,但这在复杂的包结构中不起作用:

我已经定义了模型类,如Address:

package example.model;

public class Address {
    private String street;

客户:

package example.model;

public class Customer {
    private long id;
    private String name;
    private Address address;

公共字段的父类:

package example.xml;

@XmlTransient
public class Xml {
    private Customer customer;

然后是保存具体xml XmlBoo的数据/结构的特定类:

package example.xml.boo;

@XmlRootElement
public class XmlBoo extends Xml {
    private String someSpecificField;

XmlFoo:

package example.xml.foo;

@XmlRootElement
public class XmlFoo extends Xml {}

package-info.java包括在两个提到的包example.xml.boo:

@XmlSchema(
        namespace = "http://www.example2.org/boo",
        elementFormDefault = XmlNsForm.QUALIFIED)
package example.xml.boo;

和example.xml.foo:

@XmlSchema(
    namespace = "http://www.example2.org/foo",
    elementFormDefault = XmlNsForm.QUALIFIED)

package example.xml.foo;

最后是主要方法:

package example;

public class Demo {

    public static void main(String... args) {
        generateBoo();
        generateFoo();
    }

    public static void generateBoo() {
        try {
            JAXBContext jc = JAXBContext.newInstance(XmlBoo.class);
            Marshaller m = jc.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            XmlBoo xmlBoo = new XmlBoo();

            Customer customer = new Customer();
            customer.setId(1);
            customer.setName("John");
            Address address = new Address();
            address.setStreet("Wall Street");
            customer.setAddress(address);
            xmlBoo.setCustomer(customer);
            xmlBoo.setSomeSpecificField("Specific data in Boo");

            m.marshal(xmlBoo, System.out);

        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }

    public static void generateFoo() {
        try {
            JAXBContext jc = JAXBContext.newInstance(XmlFoo.class);
            Marshaller m = jc.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            XmlFoo xmlFoo = new XmlFoo();
            Customer customer = new Customer();
            customer.setId(1);
            customer.setName("John");
            Address address = new Address();
            address.setStreet("Wall Street");
            customer.setAddress(address);
            xmlFoo.setCustomer(customer);

            m.marshal(xmlFoo, System.out);

        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }
}

我在这里尝试了两种解决方案,但都没有成功。

    < li >可以删除

有没有解决方案可以删除ns2前缀?我正在使用JDK7。

共有3个答案

史骏
2023-03-14

对于您的域模型中的每个包,您需要有一个< code>package-info注释和一个< code>@XmlSchema注释,每个包都指定相同的名称空间限定来获得所需的XML。

柳鸿博
2023-03-14

我使用了EclipseLink MOXy JAXB实现,而不是RI Metro JAXB,现在它工作了。所以看起来在Metro是bug。

Blaise Doughan的完美教程:JAXB

麻书
2023-03-14

解决方案如何获取(写入

<?xml version="1.0" encoding="UTF-8"?>
<xmlBoo xmlns="http://www.example.org/boo" xmlns:c="http://www.example.org/customer" xmlns:a="http://www.example.org/address" xmlns:h="http://www.example.org/header">
   <h:header>
      <h:id>101</h:id>
   </h:header>
   <c:customer>
      <c:id>1</c:id>
      <c:name>Yen</c:name>
      <a:address>
         <a:street>Long street</a:street>
      </a:address>
   </c:customer>
   <someBooSpecificField>Specific data in Boo</someBooSpecificField>
</xmlBoo>
  • 对于根元素及其“简单”子元素,使用默认名称空间(不带前缀)
  • 对于复杂(java中的对象),使用不同的名称空间(映射到不同的前缀)
  • 模型类在不同的包中

所以这是解决方案:

定义JAXB的MOXy实现,文件:jaxb.properties

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

为公共字段创建抽象类,为对象、文件Xml.java定义命名空间

package example.xml;

@XmlTransient
public abstract class Xml {

    private Header header;
    private Customer customer;

    @XmlElement(namespace="http://www.example.org/header")
    public Header getHeader() {
        return header;
    }

    public void setHeader(Header header) {
        this.header = header;
    }

    @XmlElement(namespace="http://www.example.org/customer")
    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
}

创建“根”类XmlBoo.java

package example.xml.boo;

@XmlRootElement
@XmlType(propOrder = {"header", "customer", "someBooSpecificField"})
public class XmlBoo extends Xml {

    private String someBooSpecificField;

    // getter & setter
}

设置命名空间和QUALIFIED为"root"类,file:example.xml.boo.package-info.java

@XmlSchema(
        namespace = "http://www.example.org/boo",
        elementFormDefault = XmlNsForm.QUALIFIED)

package example.xml.boo;

设置QUALIFIED为子级生成前缀(命名空间将被类上定义的命名空间覆盖,但必须定义),file:example.model.package-info.java

@XmlSchema(
        namespace = "http://www.example.org",
        elementFormDefault = XmlNsForm.QUALIFIED)

package example.model;

创造Header.java

package example.model;

@XmlType(namespace = "http://www.example.org/header")
public class Header {

    private long id;

    // getter & setter
}

创建客户.java

package example.model;

@XmlType(namespace = "http://www.example.org/customer", propOrder = {"id", "name", "address"})
public class Customer {

    private long id;
    private String name;
    private Address address;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @XmlElement(namespace="http://www.example.org/address")
    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

创建地址.java

package example.model;

@XmlType(namespace = "http://www.example.org/address")
public class Address {

    private String street;

    // getter & setter
}

创建MyNamespacePrefixMapper。java,方法是扩展org.eclipse.persistence.oxm.NamespacePrefixMapper

package example;
import org.eclipse.persistence.oxm.NamespacePrefixMapper;

public class MyNamespacePrefixMapper extends NamespacePrefixMapper {

    private static final String BOO_PREFIX = ""; // DEFAULT NAMESPACE
    private static final String BOO_URI = "http://www.example.org/boo";
    private static final String FOO_PREFIX = ""; // DEFAULT NAMESPACE
    private static final String FOO_URI = "http://www.example.org/foo";
    private static final String HEADER_PREFIX = "h";
    private static final String HEADER_URI = "http://www.example.org/header";
    private static final String CUSTOMER_PREFIX = "c";
    private static final String CUSTOMER_URI = "http://www.example.org/customer";
    private static final String ADDRESS_PREFIX = "a";
    private static final String ADDRESS_URI = "http://www.example.org/address";

    @Override
    public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {

        switch (namespaceUri) {
            case BOO_URI:
                return BOO_PREFIX;
            case FOO_URI:
                return FOO_PREFIX;
            case HEADER_URI:
                return HEADER_PREFIX;
            case CUSTOMER_URI:
                return CUSTOMER_PREFIX;
            case ADDRESS_URI:
                return ADDRESS_PREFIX;
            default:
                return null;
        }
    }
}

创建XML

public static void generateBoo() {
    try {
        JAXBContext jc = JAXBContext.newInstance(XmlBoo.class);
        Marshaller m = jc.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        m.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, new MyNamespacePrefixMapper());

        XmlBoo xmlBoo = new XmlBoo();
        Header header = new Header();
        header.setId(101);
        xmlBoo.setHeader(header);

        Customer customer = new Customer();
        customer.setId(1);
        customer.setName("Yen");
        Address address = new Address();
        address.setStreet("Long street");
        customer.setAddress(address);
        xmlBoo.setCustomer(customer);

        xmlBoo.setSomeBooSpecificField("Specific data in Boo");

        m.marshal(xmlBoo, System.out);
        m.marshal(xmlBoo, new File("xml_boo.xml"));

    } catch (JAXBException e) {
        e.printStackTrace();
    }
}

读取XML

public static void readBoo() {

    Object element = null;

    try {
        JAXBContext jc = JAXBContext.newInstance(XmlBoo.class);
        Unmarshaller u = jc.createUnmarshaller();
        element = u.unmarshal(new File("xml_boo.xml"));

    } catch (JAXBException e) {
        e.printStackTrace();
    }

    if (element instanceof XmlBoo) {
        XmlBoo xmlBoo = (XmlBoo) element;
        Customer customer = xmlBoo.getCustomer();

        System.out.println("INFO | xmlBoo field:  [" + xmlBoo.getSomeBooSpecificField() + "]");
        System.out.println("INFO | customer name: [" + customer.getName() + "]");
        System.out.println("INFO | address street: [" + customer.getAddress().getStreet() + "]");

    }
}
 类似资料:
  • 我使用的是WSO2 ESB 4.8.1,我希望使用XSLT修改soap消息。 我的soap消息: XSLT: 我在WSO2 ESB中创建了一个xslt文件作为本地条目。但是它添加了一个默认名称空间xmlns=“http://ws.apache.org/ns/synapse”,并将xslt改为: 因此,我的soap messsage结果是: 如何在WSO2 ESB中使用XSLT修改此元素名称而不添加

  • 问题内容: 有没有一种方法可以在python ElementTree中定义默认/无前缀的命名空间?这似乎不起作用… 这也不是: 可以,但是我必须在每个元素前加上前缀: 在OSX上使用Python 3.5。 编辑:如果答案为“否”,您仍然可以获得赏金:-)。我只是想要一个花了很多时间使用它的人的明确“否”。 问题答案: 没有简单的方法可以透明地处理默认名称空间。正如您已经提到的,为空名称空间分配非空

  • 当我从emacs苹果酒中启动lein repl:headless时,我很难调用默认名称空间。 我的project.clj有: repl条目定义: 当我喝苹果酒时,杰克从项目中走了进来。clj文件,我确实在dev.core ns中结束了: 然而,当我看到实习生时,我会: 当我重新加载命名空间时: 我的命名空间被加载。似乎内部leiningen使用(要求...)方法来加载命名空间,但在文档中找不到关于

  • 我正在寻找一个XPath表达式来获取节点的默认名称空间。 我的XML文档可能如下所示。 如果有人能给我一点提示,我将不胜感激。

  • 我有两套XSD,一套用于入站操作,另一套用于出站操作。这两个XSD集具有相似的名称空间,但由于它们来自不同的源,因此需要在同一代码集中分别维护它们。每个XSD集合都有深度嵌套的类,并生成大约650个类。我正在使用Maven JAXB插件生成Java类 如果我指定了

  • 问题内容: 我想使用JDOM读取XML文件,然后使用XPath从JDOM Document中提取数据。它可以很好地创建Document对象,但是当我使用XPath在Document中查询元素列表时,我什么也没得到。 我的XML文档在根元素中定义了一个默认名称空间。有趣的是,当我删除默认名称空间时,它成功运行了XPath查询并返回了我想要的元素。要使XPath查询返回结果,我还必须做什么? XML: