使用Java从XML中提取数据
我有以下XML代码:使用Java从XML中提取数据,java,xml,xml-parsing,Java,Xml,Xml Parsing,我有以下XML代码: <CampaignFrameResponse xmlns="http://Qsurv/api" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Message>Success</Message> <Status>Success</Status> <FrameHeight>308</FrameHeight>
<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&ReturnUrl=http%3a%2f%2flocalhost%3a8080%2feveningstar%2fhome</FrameUrl>
</CampaignFrameResponse>
这会打印出节点名称、类型和值,但将每个值分配给适当命名的变量的最佳方式是什么?例如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);
}
}
processNode(节点){
NodeList NodeList=node.getChildNodes();
for(int i=0;i
}您可以使用
DOM
,SAX
,拉式解析器
,但是使用下面的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#####");
我不建议直接解析xml(除非您被迫这样做),而是使用外部库,如。其思想是,您可以创建一个表示xml模式的对象,库将为您填充该对象。我建议使用--加上一些标界注释,您可以非常快速地从xml创建对象,只需很少的编码。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值,就需要解析。我在Java中使用XML已经有一段时间了(超过十年),并尝试了许多替代方法(自定义文本解析、专有API、SAX、DOM、Xmlbeans、JAXB等)。我学到了两件事:
- 坚持标准。永远不要使用专有API,而是使用标准JavaAPI(JAXP,包括SAX、DOM、Stax等)。您的代码将更具可移植性和可维护性,并且不会在XML库的某个版本发生更改并破坏兼容性时更改(这种情况经常发生)
- 慢慢来,一定要学习XML技术。我建议至少全面了解XSD、XSLT和XPath(XSLT所需)。如果你没有时间,那就把注意力集中在XSD上
- 尽可能利用自动XML代码生成/解析。这意味着了解XSD。从长远来看,它回报了最初的努力,随着时间的推移,代码更易于维护,解析/marsalling得到了极大的优化(通常比使用“手动”JAXP API更优化),并且可以执行XML验证(您已经拥有XSD)(检查代码更少,防止格式错误的XML破坏应用程序,集成工作更少). 最好的是,您只需编写XSD代码,几乎所有处理数据所需的Java代码(JavaBeans)都将为您生成
<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>
当然,您可以创建一个名称-值映射,并在遍历XML时更新映射。在解析结束时,您可以在映射中查找特定的键。Java不允许以编程方式创建变量,因此无法基于XML数据生成名为的变量
除了样式和可读性之外,从XML填充数据结构的决定取决于XML的定义有多好,以及它的模式在未来可能会发生多大的变化。您可以问自己这样的问题:节点名称将来会更改吗?可以引入XML小节来限定这一部分吗?这可能有助于您选择特定的解析器(SAX/DOM或更高级别的对象解析API)
当然,如果您无法控制XML定义,那么除了解析您所拥有的内容之外,您几乎无能为力。谢谢。出于某种原因,nodeValue变量一直返回null。我已经在原始问题的末尾添加了更新的代码。为什么说“xmlbeans已经死了”?
<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>