2012-10-08 39 views
1

对Java并不陌生;但对于XML解析来说相对较新。我对那里的许多XML工具知之甚少,但对其中的任何一个都不太了解。我也不是一个XML-pro。建议使用Java解析此XML

我的特别问题是这样的......我得到了一个我无法修改的XML文档,我只需要将它随机分解成Java对象。只要合理,速度并不是很重要的因素。同样,内存占用也不一定是绝对最佳的,只是没有疯狂。我只需要通读文档一次就可以解析它,然后我将它扔到bitbucket中,然后使用我的POJO。

因此,我愿意提出建议......您将使用哪种工具?
而且,您是否会建议一些起始代码来解决我的特殊需求?

这里的示例XML的一个片段,我试图工艺相关的POJO:

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

     <resource> 
     <ittype>Service_Links</ittype> 
     <links> 
      <link> 
      <path>http://www.stackoverflow.com</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

+2

SAXParser或DocumentBuilder有什么问题?另外,请接受一些以前的问题的答案。 –

+0

@JimGarrison什么也没有! :P问题是,我花了足够的时间在我不知道的事情上徘徊,只是发现他们并没有走完全程,我认为我最好问问知道的人。我现在正在查看SAXParser,但如果你有一个链接或一些示例代码来演示我可能会如何去做,那将是一个福音。 – Bane

+0

注意:我不确定是否需要“-1”...我给出了一个非常明确的说明和示例代码,说明了我的问题,并且提到了另一个类似的明确性的帖子;他们两人都解释说我一直在尝试其他技术,并且找不到合适的人选。是的,我不知道所有的技术......我先前说过。 – Bane

回答

1

好的,所以我决定采用一种解决方案(对我来说)以最合理的方式解决我的需求。我对其他建议表示歉意,但我更喜欢这条路线,因为它将大部分解析规则保留为注释,我必须编写的小程序代码非常少。

我结束了与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中,并用于向下导航几个级别以访问单个属性,而无需创建所有这些文件夹和元素POJO。尼斯。

所以我创造了这样的事情: (注:我选择,我需要按摩值使用情况的getter)

// 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对象的路径来自我在应用程序中实际使用的模型对象。因此,我有一个工厂可以将这些粗糙的对象转换成我在应用程序中实际使用的更强大的对象。

0

如果你的XML文档相对较小(如出现在这里是如此),我会使用DOM框架和XPath类。下面是从我的教程的一个部分boilerplate DOM/XPath code

File xmlFile = ... 
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
DocumentBuilder db = dbf.newDocumentBuilder(); 
Document doc = db.parse(xmlFile); 

XPath xp = XPathFactory.newInstance().newXPath(); 
String value = xp.evaluate("/path/to/element/text()", doc); 
// .. reuse xp to get other values as required 

换句话说,基本上你:

  • 让你的XML转换为Document对象,通过DocumentBuilder的;

  • 创建一个XPath对象;

  • 反复调用XPath.evaluate(),传入要求的元素路径 和您的文档。

正如你看到的,有fiddliness的让你的文档对象的保持和像所有良好的XML API一点点,它抛出愚蠢无谓过多检查的异常。但除此之外,解析结构相对固定的简单中小XML文档是毫无意义的。

0

您可以使用SAXParser或STAXParser。如果你可以承受更多的内存,那么你也可以使用DOMParser。我建议STAXParser对你最好。