分享

建议用Java解析此XML

 印度阿三17 2019-10-13

Java来说不是新手;但对于XML解析而言相对较新.我对其中的许多XML工具了解甚少,但对其中的任何一个都不了解.我也不是XML专业人士.

我的特殊问题是……我得到了一个XML文档,该文档无法修改,并且仅需要将它的随机位解析为Java对象.只要是合理的,绝对速度就不是一个很大的因素.同样,内存占用也不必绝对最佳,也不必太疯狂.我只需要通读文档一次就可以解析它,之后我将其扔到bitbucket中并仅使用我的POJO.

因此,我愿意接受建议…您将使用哪个工具?
并且,您是否可以提出一些入门代码来满足我的特殊需求?

这是示例XML和我正在尝试制作的关联POJO的片段:

<xml>
  <item id="...">
    ...
  </item>
  <metadata>
    <resources>

      <resource>
        <ittype>Service_Links</ittype>
        <links>
          <link>
            <path>http://www.</path>
            <description>Stack Overflow</description>
          </link>
          <link>
            <path>http://www.google.com</path>
            <description>Google</description>
          </link>
        </links>
      </resource>

      <resource>
        <ittype>Article_Links</ittype>
        <links>
          ...
        </links>
      </resource>

      ...

    </resources>
  </metadata>
</xml>


public class MyPojo {

    @Attribute(name="id")
    @Path("item")
    public String id;

    @ElementList(entry="link")
    @Path("metadata/resources/resource/links")
    public List<Link> links;
}

注意:这个问题最初是由this question产生的,我试图使用SimpleXml来解决它.我认为也许有人可以提出解决同一问题的不同方法.

另请注意:我真的很希望有一个CLEAN解决方案…我的意思是说,使用批注和/或xpath使用最少的代码…我想要的最后一件事是具有庞大笨拙方法的庞大类文件.那,我已经有…我正在尝试寻找一种更好的方法.

:d

解决方法:

好的,所以我选择了一个解决方案,对我来说,这似乎可以最合理地满足我的需求.我对其他建议表示歉意,但我更喜欢这条路线,因为它保留了大多数解析规则作为注释,而我必须编写的很少的过程代码非常少.

我最终选择了JAXB.最初,我以为JAXB要么从Java类创建XML,要么将XML解析为Java类,但仅使用XSD.然后,我发现JAXB具有注释,可以在没有XSD的情况下将XML解析为Java类.

我正在使用的XML文件很大而且很深,但是我只需要在这里和那里一丁点即可.我担心将来很难导航到什么地图.因此,我选择构建一个以XML建模的文件夹树…每个文件夹映射到一个元素,并且每个文件夹中都有一个POJO表示该实际元素.

问题是,有时某个元素的子元素在多个级别下具有我关心的单个属性.创建4个嵌套文件夹和一个POJO仅用于访问单个属性将是一件痛苦的事情.但这就是您使用JAXB的方式(至少,据我所知);我又在一个角落里.

然后我偶然发现了EclipseLink’s JAXB-implementation: Moxy.
Moxy有一个@XPath批注,我可以将其放置在该父POJO中,并用于向下导航多个级别以访问单个属性,而无需创建所有这些文件夹和element-POJO.尼斯.

所以我创建了这样的东西:
(注意:在需要按摩值的情况下,我选择使用吸气剂)

// maps to the root-"xml" element in the file
@XmlRootElement( name="xml" )
@XmlAccessorType( XmlAccessType.FIELD )
public class Xml {

    // this is standard JAXB
    @XmlElement;               
    private Item item;
    public Item getItem() {    
        return this.item;
    }

    ...
}

// maps to the "<xml><item>"-element in the file
public class Item {

    // standard JAXB; maps to "<xml><item id="...">"
    @XmlAttribute              
    private String id;
    public String getId() {
        return this.id;
    }

    // getting an attribute buried deep down
    // MOXY; maps to "<xml><item><rating average="...">"
    @XmlPath( "rating/@average" )    
    private Double averageRating;
    public Double getAverageRating() {
        return this.average;
    }

    // getting a list buried deep down
    // MOXY; maps to "<xml><item><service><identification><aliases><alias.../><alias.../>"
    @XmlPath( "service/identification/aliases/alias/text()" )
    private List<String> aliases;
    public List<String> getAliases() {
        return this.aliases;
    }

    // using a getter to massage the value
    @XmlElement(name="dateforindex")
    private String dateForIndex;
    public Date getDateForIndex() {
        // logic to parse the string-value into a Date
    }

}

还要注意,我采取了将XML对象与我在应用程序中实际使用的模型对象分离的方法.因此,我有一家工厂将这些原始对象转换为更坚固的对象,而这些对象实际上已在我的应用程序中使用.

来源:https://www./content-1-506901.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多