【问题标题】:JAXB - Ignore elementJAXB - 忽略元素
【发布时间】:2011-06-29 23:10:22
【问题描述】:

有什么方法可以忽略 Jaxb 解析中的元素? 我有一个大的 XML 文件,如果我可以忽略其中一个大而复杂的元素,那么它的解析速度可能会快很多。

如果它根本无法验证元素内容并解析文档的其余部分,即使该元素不正确,那就更好了。

ex:this 应该只生成 Foo.element1 和 Foo.element2

<foo>
    <element1>I want this</element1>
    <element2>And this</element2>
    <bar>
       <a>ALL of bar should be ignored</a>
       <b>this also should be ignored</b>
       <c>
           <x>a lot of C that take time to process</x>
       </c>
       <c>
            <x>a lot of C that take time to process</x>
       </c>
       <c>
          <x>a lot of C that take time to process</x>
       </c>
      <c>
          <x>a lot of C that take time to process</x>
      </c>
  </bar>
</foo>

【问题讨论】:

    标签: java xml jaxb unmarshalling


    【解决方案1】:

    假设您的 JAXB 模型如下所示:

    @XmlRootElement(name="foo")
    public class Foo {
    
       @XmlElement(name="element1")
       String element1;
    
       @XmlElement(name="element2")
       String element2;
    
       @XmlElement(name="bar")
       Bar bar;
    }
    

    然后简单地从Foo 中删除bar 字段将跳过输入文档中的&lt;bar/&gt; 元素。

    或者,用@XmlTransient而不是@XmlElement注释字段,它也会被跳过。

    【讨论】:

    • 我知道它已经一年多了......但对于标准 JAXB 来说,情况并非如此......它抱怨并抛出关于找不到丢失字段的错误。这可能是最新版本或某些旧版本......或者您正在使用在核心集上扩展的另一个 API。如果我错了,请告诉我,但我只是尝试过这个并出错了。
    • 这里是具体错误:Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions Property [property_name] appears in @XmlType.propOrder, but no such property exists. Maybe you meant [unmapped_property_name]? this problem is related to the following location: at [JAXB_object_name]
    • @jghost:听起来你已经在你的类上设置了一个 XmlType 元素,并使用了 propOrder 设置,现在 XJC 正在抱怨。也许您应该从该 propOrder 设置中删除字段名称并查看它的反应?
    • 然后它抱怨找到了unmapped_property_name,但没有在propOrder中。
    【解决方案2】:

    JAXB 将忽略任何未映射的属性。

    明智的实施(至少在我领导的EcliseLink JAXB (MOXy) 中)。当我们通过 SAX 解析器处理内容(即输入是 SAXSource)时,我们将负责构建对象的 ContentHandler 换成不对该部分进行处理的 ContentHandler(org.eclipse.persistence.oxm.unmapped.未映射内容处理程序)。当我们通过 StAX 解析器处理内容时,我们只是前进到下一个映射事件。

    如果您确实有与该节点对应的属性,您可以使用 @XmlTransient 对其进行注释以使其成为未映射的属性。

    【讨论】:

      【解决方案3】:

      所有你需要的都是将字段标记为@XmlTransient(@XmlTransient 注释应该隐藏不需要的字段)。下面的例子

      JavaEE:

      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlRootElement(name = "DeletedIds")
      public class DeletedIds {
      
          @XmlElement(name = "DeletedId")
          private List<DeletedId> id;    
      
          @XmlTransient
          @XmlElement(name = "success")
          private String success;
      
          //getters&setters
      }
      
      @XmlAccessorType(XmlAccessType.FIELD)
      public class DeletedId {
      
          private int id;
      
          //getters&setters
      }
      

      XML:

      <DeletedIds>
          <DeletedId>
              <id>1</id>
          </DeletedId>
          <DeletedId>
              <id>2</id>
          </DeletedId>
      </DeletedIds>
      

      【讨论】:

        【解决方案4】:

        您必须使用 SAX 解析器和有效“跳过”不感兴趣的节点的文档处理程序。您无法避免读取字节,但至少您可以避免让它们浪费额外的资源。

        如果您的代码需要 DOM 树,那么您基本上使用生成 DOM 节点的 SAX 文档处理程序,但“跳过”不感兴趣的节点。使用提供的 DOM 树生成器肯定不太方便,但一个不错的权衡是您不能忍受不需要的节点的额外内存开销,但您需要 DOM 树。

        【讨论】:

          猜你喜欢
          • 2021-11-20
          • 1970-01-01
          • 1970-01-01
          • 2011-01-25
          • 2011-09-28
          • 2012-10-12
          • 1970-01-01
          • 2021-05-11
          • 1970-01-01
          相关资源
          最近更新 更多