从XML使用Java提取数据(Extracting data from XML using Java

2019-09-23 22:59发布

我有以下XML代码:

<CampaignFrameResponse
  xmlns="http://Qsurv/api"
  xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Message>Success</Message>
  <Status>Success</Status>
  <FrameHeight>308</FrameHeight>   
  <FrameUrl>http://delivery.usurv.com?Key=a5018c85-222a-4444-a0ca-b85c42f3757d&amp;ReturnUrl=http%3a%2f%2flocalhost%3a8080%2feveningstar%2fhome</FrameUrl> 
</CampaignFrameResponse>

我正在试图做的是提取节点,并将其分配给一个变量。 因此,举例来说,我有一个变量叫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);
    }
}

}

Answer 1:

你的情况西河不会支持,它可用于转换对象到XML然后回来一次。 如果你的XML是从CampaignFrameResponse类的实例生成,u可以使用XStream的。

否则,你只需选中喜欢

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

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



Answer 2:

您可以使用DOMSAXPull-Parser ,但随后其良好的通过以下API去。

- JAXP & JAXB

- Castor

如:DOM解析

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#####");


Answer 3:

我一直在使用XML在Java中有一段(超过十年)和已经尝试了许多替代品(自定义文本解析,专有的API,SAX,DOM的XMLBeans,JAXB等)。 我学会了对事情:

  • 坚持标准。 切勿使用专有的API,但一个标准的Java API(JAXP,包括SAX,DOM,斯塔克斯等)。 您的代码将更加便携和maintenable并不会改变每当一个版本的XML库的变化和休息的兼容性(这种情况发生非常频繁)。
  • 把你的时间,做学习XML技术。 我建议至少XSD,XSLT和XPath(需要XSLT)的综合知识。 如果你没有时间,然后集中精力XSD。
  • 乘坐自动XML代码生成/解析的优势只要有可能。 这意味着首先要了解XSD。 付出总有回报,从长远来看原来的努力,该代码是随着时间的推移更容易维护,解析/ marsalling被大大优化(通常多于如果使用“手动” JAXP API)和XML验证(你已经有了XSD)可以进行(少检查代码,安全方面向坏的XML崩溃您的应用程序,少一体化的努力)。 最重要的事,你只写XSD代码,几乎所有的Java代码,你将需要处理的数据(Java组件)会为你生成。

Knowadays我倾向于使用代码生成每当我不得不解析一些XML这样的。 该标准也就是JAXB(的xmlbeans是死的和其他替代可能不如成熟或wideley使用)。 在你的情况我会定义作为细节定义文档尽可能的XSD(也就是说,如果你使用一个字符串,只能有几个值,不要使用“XS:字符串”类型,而是一个枚举的一个)。 它看起来是这样的:

<xs:schema attributeFormDefault="unqualified"
    elementFormDefault="qualified" targetNamespace="http://Qsurv/api"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="CampaignFrameResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element type="xs:string" name="Message" />
                <xs:element type="Status" name="Status" />
                <xs:element type="xs:short" name="FrameHeight" />
                <xs:element type="xs:anyURI" name="FrameUrl" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <<xs:simpleType name="Status">
        <xs:annotation>
            <xs:appinfo>
                <jaxb:typesafeEnumClass>
                    <jaxb:typesafeEnumMember name="SUCCESS"
                        value="Success" />
                    <jaxb:typesafeEnumMember name="FAILURE"
                        value="Failure" />
                </jaxb:typesafeEnumClass>
            </xs:appinfo>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:enumeration value="Success" />
            <xs:enumeration value="Failure" />
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

现在,它是使用JAXB工具(见XJC编译器选项)来生成代码,看看如何编组/解组生成的Java组件从/到XML一对例子的问题。



Answer 4:

你当然可以创建一个名称 - 值映射,当你遍历XML更新地图。 在解析结束时,你可以看看在地图上的特定按键。 Java没有让你创建变量编程,所以你将无法产生基于XML的数据,其名称的变量。

除了风格和可读性,你决定从XML填充数据结构依赖于XML如何定义的是,有多少将它的模式可能会在未来有可能发生变化。 你可以问自己这样的问题:可以在以后的节点名称的改变? 可以将XML小节介绍,将外接这一节? 这可以帮助你选择一个特定的解析器(SAX / DOM或更高级别的对象解析API)。

当然,如果你对XML定义没有控制有一点你可以做比分析你有什么其他的。



Answer 5:

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



Answer 6:

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



文章来源: Extracting data from XML using Java