我有以下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&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);
}
}
}
答案 0 :(得分:2)
您可以使用DOM
,SAX
,Pull-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#####");
答案 1 :(得分:2)
我已经在Java中使用XML了一段时间(十多年)并尝试了很多替代方案(自定义文本解析,专有API,SAX,DOM,Xmlbeans,JAXB等)。我学到了一些东西:
众所周知,每当我必须解析某些XML时,我倾向于使用代码生成。标准是JAXB(xmlbeans已经死了,其他替代品可能不会成熟或使用广泛)。在您的情况下,我将定义一个XSD,尽可能详细地定义您的文档(即如果您使用只能有多个值的String,请不要使用“xs:string”类型,而是使用枚举的类型)。它看起来像这样:
<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编译器选项)来生成代码,并查看有关如何从/向XML封送/解组生成的Java Bean的示例。
答案 2 :(得分:1)
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值,则需要解析。
答案 3 :(得分:1)
当然,您可以在遍历XML时创建名称 - 值映射并更新映射。在解析结束时,您可以在地图中查找特定键。 Java不允许您以编程方式创建变量,因此您将无法基于XML数据生成其名称的变量。
除了样式和可读性之外,您决定从XML填充数据结构取决于XML的定义有多好以及未来其架构可能会发生多大变化。您可以问自己一些问题:节点名称将来是否会发生变化?是否可以引入限制此部分的XML子部分?这可能有助于您选择某个解析器(SAX / DOM或更高级别的对象解析API)。
当然,如果您无法控制XML定义,除了解析您所拥有的内容之外,您几乎无能为力。
答案 4 :(得分:0)
我不建议直接解析xml(除非你被迫这样做),而是使用外部库,如http://x-stream.github.io/。我们的想法是,您可以创建一个表示您的xml架构的对象,并且库将为您填充该对象。
答案 5 :(得分:0)
我建议使用 - x-stream.github.io - 使用一些分界注释,你可以非常快速地用XML创建对象。