我在存储一些测试数据的XML文件中有以下数据。
<root>
<event>
<auth>
<admin>
<username>[email protected]</username>
<password>pass^&*%s</password>
<name>temp</name>
</admin>
<normal-user>
<username>[email protected]</username>
<password>test45#</password>
</normal-user>
</auth>
</event>
</root>
我正在尝试从键值对中的xml读取数据。例如event.auth.admin.username = [email protected]
。如果我将所有其他数据节点都置于admin下,但如果我使用另一个节点<normal-user>
,则它将此节点名称附加在较旧的节点中。
实际:event.auth.admin.normal-user.username = [email protected]
预期:event.auth.normal-user.username = [email protected]
我正在使用以下代码:
private StringBuilder keyName = new StringBuilder(); Logger printLog = Logger.getLogger("API Testing Logger"); public void loadXml() { File folder = new File("resources"); File[] listOfFiles = folder.listFiles(); for (File file : listOfFiles) { if (file.isFile() && file.getName().endsWith(".xml")) { printLog.log(Level.INFO, "xml file loaded : " + file.getName()); try { File inputFile = new File(folder.getAbsolutePath() + "/" + file.getName()); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(inputFile); doc.getDocumentElement().normalize(); new XmlLoader().fillDataInProperty(doc.getDocumentElement()); } catch (Exception e) { e.printStackTrace(); } } } }
public void fillDataInProperty(Node node) { if (!node.getNodeName().equals("root")) { if (node.getChildNodes().getLength() == 1) { keyName.append(node.getNodeName()); int i = keyName.indexOf(node.getNodeName()); if (i != -1) { keyName.delete(i, i + keyName.length()); } } else { keyName.append( node.getNodeName().concat(".")); } } NodeList nodeList = node.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node currentNode = nodeList.item(i); if (currentNode.getNodeType() == Node.ELEMENT_NODE) { fillDataInProperty(currentNode); } } }
我在存储一些测试数据的XML文件中有以下数据。
问题是当您有多个子节点时,这是一种递归解决方案,试图解决该问题:
public void loadXml() {
// ..
new XmlLoader().fillDataInProperty(doc.getDocumentElement(), "");
}
public void fillDataInProperty(Node node, String parent) {
if (parent.isEmpty()) {
parent = node.getNodeName();
} else {
parent = parent + "." + node.getNodeName();
}
NodeList childNodes = node.getChildNodes();
for (int i=0; i< node.getChildNodes().getLength(); i++) {
Node currentNode = childNodes.item(i);
if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
fillDataInProperty(currentNode, parent);
} else if (currentNode.getNodeType() == Node.TEXT_NODE && childNodes.getLength() == 1) {
String content = currentNode.getTextContent().replace("\n", "").replace("\r", "").trim();
keyName.append(parent + " = " + content + "\n");
}
}
}
和System.out.println(p.keyName.toString());
现在打印:
root.event.auth.admin.username = [email protected]
root.event.auth.admin.password = passs
root.event.auth.admin.name = temp
root.event.auth.normal-user.username = [email protected]
root.event.auth.normal-user.password = test45#
我发现将算法分解为以下步骤更容易:
这是一个完整的示例:
static String XML =
"<root>\n" +
" <event>\n" +
" <auth>\n" +
" <admin>\n" +
" <username>[email protected]</username>\n" +
" <password>pass</password>\n" +
" <name>temp</name>\n" +
" </admin>\n" +
"\n" +
" <normal-user>\n" +
" <username>[email protected]</username>\n" +
" <password>test45#</password>\n" +
" </normal-user>\n" +
"\n" +
" </auth>\n" +
" </event>\n" +
"</root>";
public static void main(String[] args) throws Exception {
Document doc = DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.parse(new ByteArrayInputStream(XML.getBytes()));
Element root = doc.getDocumentElement();
List<Element> leafs = new ArrayList<>();
gatherLeafElements(root, leafs);
for(Element e: leafs) {
System.out.println(createProperty(root, e));
}
}
static String createProperty(Element root, Element leaf) {
List<String> stack = new ArrayList<>();
Element tmp = leaf;
while(tmp != root) {
stack.add(0, tmp.getNodeName());
tmp = (Element) tmp.getParentNode();
}
String property = stack
.stream()
.collect(Collectors.joining("."));
return property + "=" + leaf.getTextContent().trim();
}
static void gatherLeafElements(Element e, List<Element> leafs) {
if (isLeafElement(e)) {
leafs.add(e);
return;
}
Node child = e.getFirstChild();
while(child != null) {
if (child.getNodeType() == Node.ELEMENT_NODE) {
gatherLeafElements((Element) child, leafs);
}
child = child.getNextSibling();
}
}
static boolean isLeafElement(Element e) {
Node child = e.getFirstChild();
while(child != null) {
if (child.getNodeType() == Node.ELEMENT_NODE) {
return false;
}
child = child.getNextSibling();
}
return true;
}