Java + XML |从同名节点的深层树中访问特定节点
所以,我相信答案可能会相当简单。尽管如此,我一直试图弄清楚这个问题已经一个多星期了,而且没有运气。我正在尝试为桌面/操作系统模拟器游戏创建一个FileSystem。Java + XML |从同名节点的深层树中访问特定节点
目前,文件系统看起来是这样的:(精简略)
<system>
<info> <!-- Default information/data for this system -->
<top dir="/"/>
</info>
<files> <!-- File and Directory structure for this system -->
<dir name="home" owner="0" group="0" ownerp="rwx" groupp="r-x" otherp="r-x">
<dir name="cyanite" owner="1000" group="1000" ownerp="rwx" groupp="rwx" otherp="r-x">
<dir name="folder" owner="1000" group="1000" ownerp="rwx" groupp="rwx" otherp="r-x">
<dir name="folder" owner="1000" group="1000" ownerp="rwx" groupp="rwx" otherp="r-x">
<dir name="folder" owner="1000" group="1000" ownerp="rwx" groupp="rwx" otherp="r-x">
</dir>
</dir>
</dir>
</dir>
</dir>
<dir name="bin" owner="0" group="0" ownerp="rwx" groupp="r-x" otherp="r-x">
</dir>
<dir name="etc" owner="0" group="0" ownerp="rwx" groupp="r-x" otherp="r-x">
</dir>
<dir name="usr" owner="0" group="0" ownerp="rwx" groupp="r-x" otherp="r-x">
</dir>
</files>
</system>
这里是我马虎WIP代码尝试从文件中读取:
System.out.println(fileNavigator.getDirectory("home"));
public ArrayList<String> getDirectory(String path) {
Document doc = ExitParser.getDocFromZip(system); // This loads the save file and returns the doc
NodeList dataList = doc.getElementsByTagName("files");
NodeList dataList2 = parsePath(dataList, path);
ArrayList<String> stringList = new ArrayList<String>();
try {
for(int i=0; i < dataList2.getLength(); i++) {
Node dataItem = dataList2.item(i);
Element elementDataItem = (Element)dataItem;
stringList.add(elementDataItem.getAttribute("name"));
}
} catch (NullPointerException e) {
stringList.add("NullPointerException");
}
return stringList;
}
public NodeList parsePath(NodeList nodelist, String path) {
Document doc = ExitParser.getDocFromZip(system); // This loads the save file and returns the doc
NodeList dataList = doc.getElementsByTagName("info");
if (path.startsWith(ExitParser.getAttributeValue(dataList, "top", "dir"))) {
// This simply grabs "top" from the FileSystem <info> area and strips it.
path.replaceFirst(Pattern.quote(ExitParser.getAttributeValue(dataList, "top", "dir")), "");
}
List<String> pathList = new ArrayList<String>();
if (path.contains("/")) {
pathList = new ArrayList<String>(Arrays.asList(path.split("/")));
} else if (path.contains("\\")) {
pathList = new ArrayList<String>(Arrays.asList(path.split("\\")));
} else {
pathList.add(path);
}
for (String string : pathList) {
System.out.println(string);
nodelist = ExitParser.getNextSetAttr(nodelist, string);
}
return nodelist;
}
public static NodeList getNextSetAttr(NodeList data, String attrName) {
try {
for(int i=0; i < data.getLength(); i++){
Element dataElement = (Element)data.item(i);
NodeList nodeList = dataElement.getElementsByTagName("dir");
Element nodeElement = (Element)nodeList.item(0);
if(nodeElement.hasAttribute("name")){
if (nodeElement.getAttribute("name").contains(attrName)) {
System.out.println(true);
return nodeList;
}
}
}
}
catch(Exception ex) {
System.out.println(ex.getMessage());
}
return null;
}
使用上面的代码,我预计输出为[cyanite]
,但我得到[home, cyanite, folder, folder, folder, bin, etc, usr]
。
如果我将System.out.println(fileNavigator.getDirectory("home"));
更改为System.out.println(fileNavigator.getDirectory("home/cyanite"));
,那么我会得到[cyanite]
。如果我将"home/cyanite"
更改为"bin"
,我会得到[NullPointerException]
。
对于[home, cyanite, folder, folder, folder, bin, etc, usr]
这个问题似乎是父节点被添加到列表(即home,bin等,usr)以及所有子节点(即:文件夹,文件夹,文件夹)的问题。在我的使用案例中,我只希望获取当前节点的子节点,而不是节点的子节点。
虽然我不确定为什么我不能访问home
以外的其他文件夹。
该问题是由于代码一次接收所有同名节点而造成的。但是,有人可以通过做类似于this answer(StackOverflow |按名称仅获取XML的直接子元素)中建议的内容来获得直接子项。在那里,他们利用.getFirstChild()
和.getNextSibling()
以仅循环通过当前级别。