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

取消对具有不同名称空间的JAXB子级的排序

鲁乐
2023-03-14

我是XML和JAXB的新手。我读了很多关于XML、名称空间声明等的文章,但我目前面临着一个无法解决的JAXB问题。EPO上有一个关于响应文档的XSD文件。我可以与客户端一起调用EPO web服务并获取返回文档。我将显示这样一个返回文档的第一行。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type='text/xsl' href='/3.0/style/rplus.xsl' ?>
<ns2:world-patent-data 
    xmlns:ns2="http://ops.epo.org" 
    xmlns:ns3="http://www.epo.org/register" 
    xmlns:ns4="http://www.w3.org/1999/xlink" 
    xmlns:ns5="http://www.epo.org/cpcexport" 
    xmlns:ns6="http://www.epo.org/cpcdefinition">
    <ns2:meta name="elapsed-time" value="15"/>
    <ns2:register-search total-result-count="1">
        <ns2:query syntax="CQL">application=EP99203729</ns2:query>
        <ns2:range begin="1" end="1"/>
        <ns3:register-documents produced-by="RO">
            <ns3:register-document date-produced="20151028" dtd-version="1.0" lang="en" produced-by="RO" status="NO OPPOSITION FILED WITHIN TIMELIMIT">
                ...
            </ns3:register-document>
        </ns3:register-documents>
    </ns2:register-search>
</ns2:world-patent-data >

正如您所看到的,定义了多个名称空间,但在文档正文中使用的名称空间只有两个,即ns2和NS3。我的问题是解组ns3:register-documents实体。我使用Netbeans创建了我的JAXB类。使用了EPO中的XSD文件。Netbeans只创建了属于该XSD的类,即没有N2:Register-Search或N2:World-Patent-Data类生成。我尝试了以下内容:我尝试对整个文档进行解组,并假设JAXB解组器将自动找到ns3:register-documents元素,将其标识为root并返回它。我还尝试使用XPATH从XML文档中提取ns3:register-documents元素,并只对该元素进行解组。这也行不通。一个javax.xml.bind.UnMarshalException:引发意外元素。我想我必须告诉JAXB,ns3:register-documents从哪里开始,它属于哪个名称空间等等。不幸的是,我不知道怎么做。非常感谢你的帮助。

共有1个答案

萧德馨
2023-03-14

您可能已经从那个角落下载了所有的XML模式,并生成了所有的Java类模式,包括通信层的模式。不过,我可以同情你,避免那些额外的麻烦:-)

但是现在您必须进行一些显式的XML处理:将XML解析为DOM树,获取您感兴趣的节点并从中解组。如下所示:

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
    DocumentBuilder db = dbf.newDocumentBuilder();
        dbf.setNamespaceAware(true);
    Document document = db.parse(new File( "xxx.xml" ) );
    Element rootNode = document.getDocumentElement();
    if (! rootNode.getLocalName().equals("world-patent-data")) {
        throw new IllegalStateException( "bad document" );
    }
    NodeList infos = 
        rootNode.getElementsByTagNameNS("http://ops.epo.org", "register-search");
    if( infos.getLength() == 0 ){
        throw new IllegalStateException( "not a register search" );
    }   
    Element info = (Element)infos.item(0);
    NodeList docs = 
        info.getElementsByTagNameNS("http://www.epo.org/register", "register-documents");
    if( docs.getLength() == 0 ){
        throw new IllegalStateException( "no register-documents" );
    }   
    Element newTop = (Element)docs.item(0);
    System.out.println( newTop.getTagName() );
    JAXBContext jc = JAXBContext.newInstance( "org.epo.register" );
    Unmarshaller u = jc.createUnmarshaller();
    JAXBElement jbe = 
        (JAXBElement)u.unmarshal( newTop );
    RegisterDocuments rds = jbe.getValue();
    System.out.println( rds.getProducedBy() );
 类似资料:
  • 我需要加载XML文件,但存在两种相同的文件格式,只是名称空间不同-在我的简化示例中,: : 引用了一个特定的名称空间,因此我不能以相同的方式处理这两个文件: 给出输出: 目前,我已经以一种次优的方式进行了工作,通过使用https://stackoverflow.com/a/50800021-但如果可能的话,我想将其转移到JAXB中。 输出:

  • 我正在尝试使用jaxb创建XML,如下所示,其中子元素有单独的命名空间。 我的班级 但我正在像下面这样生成xml,其中子模式位于根级别。 我在package-info.java定义了@xmlschema 当我生成xml时,子元素的名称空间没有被生成,我只得到根元素的命名空间。

  • 我从 3 个不同的客户端收到 3 个不同的 xml 输入: 来自客户端1的输入1:(命名空间前缀:,命名空间url:) 来自客户端 2 的输入 2:(命名空间前缀:,命名空间 URL:) 从客户端3输入3:(名称空间前缀: 时,< li >调用< code>String.replace() 这让我想到这种变量命名空间的方法是否应该完全可以接受。如果有什么可以改进此代码的方法,那么我要求社区在答案/

  • 我需要创建和解析一组结构非常相似但不幸的是在几个不同的命名空间中定义的xml。我通常能够使用JAXB解析和创建所有XML,但似乎在让JAXB处理命名空间定义方面存在一些问题。下面的简单示例应该可以说明这个问题。 如果我定义一个带有类似如下命名空间的带注释的类: 并定义该类使用的另一个类,而不指定命名空间 同时,我有以下包级定义,允许我在<code>总线 我有一个这样的xml: 然后,我可以简单地使

  • 我需要你在JAXB编组方面的帮助。这是关于命名空间的。我在这个令人惊叹的网站上阅读了不同的博客和很多答案,但我还没有意识到如何解决我的问题。 我需要用一些复杂的(至少对我来说)名称空间生成一个XML。 如您所见,该XML具有 < code > xmlns:xsi = " http://www . w3 . org/2001/XML schema-instance " 和 http://www.sa

  • 问题内容: 我有一个这样的架构层次结构: 一个文件夹中的所有文件都具有相同的命名空间。 现在,我想将名称空间映射到特定的Java包(我不能更改名称空间)。 我找到了将架构绑定到程序包的解决方案。但是然后我必须为每个xsd文件创建一个条目: 有没有一种方法可以直接定义名称空间和程序包名称之间的绑定? 另一种方法是在maven中定义包: 但是然后我必须为每个文件夹创建一个执行,这并不是我真正想要的。