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

JAXB-在解组期间检索命名空间映射

储法
2023-03-14

这是我的包信息级别映射

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.company.com/commons", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, xmlns = {
    @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://www.company.com/commons", prefix = "commons")
})
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.company.com/structure-modification-evaluation", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, xmlns = {
    @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://www.company.com/structure-modification-evaluation", prefix = "structure-modification-evaluation")
})

这是我的输入xml(只是根元素)

<input xmlns="http://www.company.com/structure-modification-evaluation" xmlns:p1="http://www.company.com/commons">
   ...xml content
</input>

您可以注意到URI“http://www.company.com/commons“使用不同的前缀映射。<br>解组工作正常,使用

JAXBContext ctx = JAXBContext.newInstance("path/to/ObjectFactory");
Input input = ctx.createUnmarshaller().unmarshal(...)

在一些输入修改之后,我需要将文件持久化(使用原始的名称空间前缀)。

问题是:< br >在解组期间,有什么方法可以检索名称空间/前缀映射吗?

共有1个答案

庞元青
2023-03-14

以这种方式使用 XMLEventReader 解析:

public class SchemaNamespaceCollectorEventReader extends EventReaderDelegate
{
    @SuppressWarnings("serial")
    public class SchemaDocumentNamespace implements Serializable
    {   
        /** targetNamespace */
        private String targetNamespaceURI;
        /** Keyed by prefix */
        private Map<String, String> namespaceURIMapping = new LinkedHashMap<String, String>();

        public void setTargetNamespaceURI(String targetNamespaceURI)
        {
            this.targetNamespaceURI = targetNamespaceURI;
        }
        public String getTargetNamespaceURI()
        {
            return targetNamespaceURI;
        }
        public Map<String, String> getNamespaceURIMapping()
        {
            return Collections.unmodifiableMap(namespaceURIMapping);
        }
        public void addNamespaceURIMapping(String prefix, String URI)
        {
            namespaceURIMapping.put(prefix, URI);
        }
        public final NamespaceContext getNamespaceContext()
        {
            return new SimpleNamespaceContext(namespaceURIMapping);
        }

        @Override
        public String toString()
        {
            return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
        }
    }

    private SchemaDocumentNamespace namespaces;
    public SchemaNamespaceCollectorEventReader(XMLEventReader xsr)
    {
        super(xsr);
    }

    @Override
    public XMLEvent nextEvent() throws XMLStreamException
    {
        final XMLEvent e = super.nextEvent();
        if(e.getEventType() == XMLStreamConstants.START_ELEMENT)
        {
            final StartElement startElement = e.asStartElement();
            if(startElement.getName().equals(new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "schema")))
            {
                this.namespaces = collectXmlns(startElement);
            }
        }
        return e;
    }

    private SchemaDocumentNamespace collectXmlns(StartElement e)
    {
        final SchemaDocumentNamespace namespaces = new  SchemaDocumentNamespace();
        final Attribute targetNSAttr = e.getAttributeByName(new QName("targetNamespace"));
        if(targetNSAttr != null)
        {
            namespaces.setTargetNamespaceURI(targetNSAttr.getValue());
        }
        final NamespaceContext nsCtx = e.getNamespaceContext();
        for(final Iterator i = e.getNamespaces();i.hasNext();)
        {
            final Namespace ns = (Namespace) i.next();
            final String uri = ns.getNamespaceURI();
            final String prefix = ns.getPrefix();
            final String value = ns.getValue();

            namespaces.addNamespaceURIMapping(prefix, value);
        }

        return namespaces;
    }

    public SchemaDocumentNamespace getNamespaces()
    {
        return namespaces;
    }
}

用法:

final XMLInputFactory xif = XMLInputFactory.newInstance();
final SchemaNamespaceCollectorEventReader xsr = new SchemaNamespaceCollectorEventReader(xif.createXMLEventReader(url.openStream()));
jaxbContext.createUnmarshaller().unmarshal(xrs);
return xsr.getNamespaces()
 类似资料:
  • 我有一个为安全令牌构建的XML。这些包含基于WS-Trust的名称空间,但是当我解组这个XML以创建< code > RequestSecurityTokenResponseCollection 对象时,它用< code>ns1 、< code>ns2 、< code>ns3等名称空间替换了这些名称空间。 是否有一种方法可以在不更改输入XML中的名称空间和名称空间前缀的情况下解组XML? 这是我一

  • 我的代码如下: 我怎样才能让它工作?如果我的xml标记有一些相关元素,如上面的“xmlns”,则JAXB解组器会抛出异常。 这是我第一次这么做,所以我对JAXB、解编等都一无所知。我在苦苦挣扎任何帮助都是好的。 编辑StackTrace:

  • 当我试图使用包含名称空间的JAXB将xml转换为Java对象时,会发生错误。 示例示例:' Zeta Walnes ` 我需要忽略名称空间

  • 目前,我正在映射一个命名空间,通过创建一个包的package-info.java文件与以下注释。 正如您所看到的,我的一个命名空间没有前缀,而另一个命名空间有前缀,这目前是有效的,但我想要另一种映射命名空间的方式,而不必创建单独的文件,任何人都知道我如何将命名空间映射放在类中的注释旁边? 在我的XML中,名称空间声明位于根元素中,如下所示: 我的类声明和注释类似于根元素的下面。 谢谢

  • 问题内容: 这是我的xml,需要将其转换为Java。我用过jaxb 并引发以下异常javax.xml.bind.UnmarshalException:意外元素(uri:“ http://www.ae.com/Event/Load ”,本地:“ Order”)。期望的元素是<{} lm:Order> 这是我的解组代码 订购Pojo班 您能否也帮助我阅读,当前正在读取文件,需要读取为XML Strin

  • 我有一个xml,我正在尝试解体。它失败,因为它缺少必需的命名空间。 需要成为: 这个NamespaceFilter的例子只处理一个名称空间。我需要一个将追加两个名称空间。