我正在解析一个动态生成的xml,我对从xml中提取数据有一些疑问。我的代码如下,
try {
File file = new File("test.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
System.out.println("Root element " + doc.getDocumentElement().getNodeName());
NodeList nodeLst = doc.getElementsByTagName("control");
System.out.println("Information of all fields");
for (int s = 0; s < nodeLst.getLength(); s++) {
Node fstNode = nodeLst.item(s);
if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
Element fstElmnt = (Element) fstNode;
NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("value");
Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
NodeList fstNm = fstNmElmnt.getChildNodes();
System.out.println("Value: " + ((Node) fstNm.item(0)).getNodeValue());
NodeList lstNmElmntLst = fstElmnt.getElementsByTagName("label");
Element lstNmElmnt = (Element) lstNmElmntLst.item(0);
NodeList lstNm = lstNmElmnt.getChildNodes();
System.out.println("Label: " + ((Node) lstNm.item(0)).getNodeValue());
NodeList hintElmntLst = fstElmnt.getElementsByTagName("hint");
Element hintElmnt = (Element) hintElmntLst.item(0);
NodeList hint = hintElmnt.getChildNodes();
System.out.println("Hint: " + ((Node) hint.item(0)).getNodeValue());
}
}
} catch (Exception e) {
e.printStackTrace();
}
我的XML格式
<metadata>
<control name="first-name">
<resources lang="en">
<label>First Name</label>
<hint>your first name</hint>
</resources>
<resources lang="fr">
<label>Prénom</label>
<help />
<hint>
Votre prénom
</hint>
</resources>
<value> Hari </value>
</control>
</metadata>
我有以下问题,
1)如果相应字段存在提示,则只有<hint>
存在于xml中,否则它不会退出。因此,如果标签不存在,那么我得到错误。那么我们如何检查标签是否存在?如果标签存在,那么我们将获得标签内容。
2)对于值字段如果字段值不为null,那么它将正常工作。如果字段值为null,则xml中的标记将显示为<value/>
,因此如果字段值为null,则我的代码未检测到<value/>
标记并收到错误。那么如果字段值带有空值,我怎么能将字段值设置为null。
请提出任何建议..
答案 0 :(得分:3)
你只需要检查你得到的元素节点。
如果您有<value />
,那么它将没有子节点:
NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("value");
Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
if (fstNmElmnt.hasChildNodes()) {
NodeList fstNm = fstNmElmnt.getChildNodes();
System.out.println("Value: " + ((Node) fstNm.item(0)).getNodeValue());
} else {
System.out.println("Value: null");
}
如果您没有提示,那么您将获得0长度列表:
NodeList hintElmntLst = fstElmnt.getElementsByTagName("hint");
if (hintElmntLst.getLength() > 0) {
Element hintElmnt = (Element) hintElmntLst.item(0);
NodeList hint = hintElmnt.getChildNodes();
System.out.println("Hint: " + ((Node) hint.item(0)).getNodeValue());
}
回答评论问题:如果您只想阅读英文资源,那么只需在您所拥有的内容中引入另一个循环:
NodeList resources = fstElmnt.getElementsByTagName("resources");
for (int k = 0; k < resources.getLength(); k++) {
Node resNode = resources.item(k);
if (resNode.getNodeType() == Node.ELEMENT_NODE) {
Element resElement = (Element)resNode;
if (resElement.hasAttribute("lang") &&
resElement.getAttribute("lang").equals("en")) {
//your existing code here for value, label, hint
}
}
}
您只需更改代码的值,标签和提示,以便只访问resElement
。例如:
NodeList fstNmElmntLst = resElement.getElementsByTagName("value");
而不是fstElmnt.getElementsByTagName("value");
答案 1 :(得分:1)
没关系?如果我改变它如下;
而不是这个;
NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("value");
Element fstNmElmnt = (Element) fstNmElmntLst.item(0);
NodeList fstNm = fstNmElmnt.getChildNodes();
System.out.println("Value: " + ((Node) fstNm.item(0)).getNodeValue());
改变它;
System.out.println("Value: " + getTagValue("value", fstElmnt) );
getTagValue方法是;
private static String getTagValue(String tag, Element eElement) {
Node nNode = eElement.getElementsByTagName(tag).item(0);
if (nNode == null) {
return null;
}
NodeList nlList = nNode.getChildNodes();
Node nValue = (Node) nlList.item(0);
if (nValue == null)
return null;
return nValue.getNodeValue();
}
答案 2 :(得分:1)
改用XPath。代码将很多更易于阅读和维护:
XPath xp = XPathFactory.newInstance().newXPath();
NodeList controls = (NodeList) xp.evaluate("//control", doc,
XPathConstants.NODESET);
for (int i = 0; i < controls.getLength(); ++i) {
Node c = controls.item(i);
String label = xp.evaluate(".//label", c);
String hint = xp.evaluate(".//hint", c);
String value = xp.evaluate(".//value", c);
System.out.printf("%s, %s, %s\n", label, hint, value);
}
更新:
要根据语言进行选择,只需在资源元素中包含谓词:
String label = xp.evaluate("resources[@lang='en']/label", c);
String hint = xp.evaluate("resources[@lang='en']/hint", c);
String value = xp.evaluate("resources[@lang='en']/value", c);
或者,您当然可以选择resources元素,然后选择每个所需的子元素。