使用Java从XML中提取数据

我有以下XML代码:

 Success Success 308 http://delivery.usurv.com?Key=a5018c85-222a-4444-a0ca-b85c42f3757d&ReturnUrl=http%3a%2f%2flocalhost%3a8080%2feveningstar%2fhome  

我要做的是提取节点并将它们分配给变量。 因此,例如,我有一个名为FrameHeight的变量, FrameHeight包含值308

这是我到目前为止的Java代码:

 private void processNode(Node node) { NodeList nodeList = node.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node currentNode = nodeList.item(i); if (currentNode.getNodeType() == Node.ELEMENT_NODE) { //calls this method for all the children which is Element LOG.warning("current node name: " + currentNode.getNodeName()); LOG.warning("current node type: " + currentNode.getNodeType()); LOG.warning("current node value: " + currentNode.getNodeValue()); processNode(currentNode); } } } 

这会打印出节点名称,类型和值,但是将每个值分配给适当命名的变量的最佳方法是什么? 例如, int FrameHeight = 308

这是我更新的代码,其中nodeValue变量保持返回null:

 processNode(Node node) { NodeList nodeList = node.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node currentNode = nodeList.item(i); if (currentNode.getNodeType() == Node.ELEMENT_NODE) { //calls this method for all the children which is Element String nodeName = currentNode.getNodeName(); String nodeValue = currentNode.getNodeValue(); if(nodeName.equals("Message")) { LOG.warning("nodeName: " + nodeName); message = nodeValue; LOG.warning("Message: " + message); } else if(nodeName.equals("FrameHeight")) { LOG.warning("nodeName: " + nodeName); frameHeight = nodeValue; LOG.warning("frameHeight: " + frameHeight); } processNode(currentNode); } } 

}

Xstream在你的情况下不支持,它可以用于将对象转换为xml然后再次返回。 如果您的xml是从CampaignFrameResponse类的实例生成的,则可以使用xstream。

否则你只需检查一下

 String nodeName = currentNode.getNodeName() String nodeValue = currentNode.getNodeValue() ; if( nodeName.equals("Message")){ message = nodeValue ; } else if( nodeName.equals("FrameHeight") { frameHeight = nodeValue ; } 

如果需要int值,则需要解析。

您可以使用DOMSAXPull-Parser ,但最好还是使用以下API。

JAXP & JAXB

Castor

例如:DOM PARSING

 DocumentBuilderFactory odbf = DocumentBuilderFactory.newInstance(); DocumentBuilder odb = odbf.newDocumentBuilder(); InputSource is = new InputSource(new StringReader(xml)); Document odoc = odb.parse(is); odoc.getDocumentElement().normalize (); // normalize text representation System.out.println ("Root element of the doc is " + odoc.getDocumentElement().getNodeName()); NodeList LOP = odoc.getElementsByTagName("response"); Node FPN =LOP.item(0); try{ if(FPN.getNodeType() == Node.ELEMENT_NODE) { Element token = (Element)FPN; NodeList oNameList1 = token.getElementsByTagName("user_id"); Element firstNameElement = (Element)oNameList1.item(0); NodeList textNList1 = firstNameElement.getChildNodes(); this.setUser_follower_id(Integer.parseInt(((Node)textNList1.item(0)).getNodeValue().trim())); System.out.println("#####The Parsed data#####"); System.out.println("user_id : " + ((Node)textNList1.item(0)).getNodeValue().trim()); System.out.println("#####The Parsed data#####"); 

我已经在Java中使用XML了一段时间(超过十年)并尝试了许多替代方案(自定义文本解析,专有API,SAX,DOM,Xmlbeans,JAXB等)。 我学到了一些东西:

  • 坚持标准。 永远不要使用专有API,而是使用标准Java API(JAXP,包括SAX,DOM,Stax等)。 您的代码将更具可移植性和可维护性,并且只要XML库的版本发生更改并破坏兼容性(这种情况经常发生),就不会更改。
  • 花点时间学习XML技术。 我建议至少全面了解XSD,XSLT和XPath(XSLT所需)。 如果你没有时间,那么请专注于XSD。
  • 尽可能利用自动XML代码生成/解析。 这意味着了解XSD。 从长远来看,它可以回报原始的努力,随着时间的推移,代码更易于维护,解析/ marsalling得到了极大的优化(通常比使用“手动”JAXP API更多)和XMLvalidation(你已经拥有XSD)可以执行(减少检查代码,防止形成错误的XML导致应用程序崩溃,减少集成工作)。 最好的是,你只编写XSD代码,几乎所有需要处理数据的Java代码(Java Beans)都将为你生成。

知道每当我必须解析一些像这样的XML时,我倾向于使用代码生成。 标准是JAXB(xmlbeans已经死了,其他替代品可能不会成熟或使用广泛)。 在您的情况下,我将定义一个XSD,尽可能详细地定义您的文档(即如果您使用只能有多个值的String,请不要使用“xs:string”类型,而是使用枚举的类型)。 它可能看起来像这样:

            <               

现在,需要使用JAXB工具(请参阅xjc编译器选项)来生成代码,并查看有关如何将生成的Java Bean从/向XML编组/解组的一对示例。

您当然可以创建名称 – 值映射并在遍历XML时更新映射。 在解析结束时,您可以在地图中查找特定键。 Java不允许您以编程方式创建变量,因此您将无法基于XML数据生成其名称的变量。

除了样式和可读性之外,您决定从XML填充数据结构取决于XML的定义有多好以及未来其架构可能会发生多大变化。 您可以问自己一些问题:节点名称将来是否会发生变化? 是否可以引入限制此部分的XML子部分? 这可能有助于您选择某个解析器(SAX / DOM或更高级别的对象解析API)。

当然,如果您无法控制XML定义,除了解析您所拥有的内容之外,您几乎无能为力。

我建议使用 – x-stream.github.io – 使用一些分界注释,你可以非常快速地用XML创建对象,只需很少的编码。

我不建议直接解析xml(除非你被迫这样做),而是使用外部库,比如http://x-stream.github.io/ 。 我们的想法是您可以创建一个表示您的xml架构的对象,并且库将为您填充该对象。