问题描述
我想修改xml-structure以创建一个具有类似xml结构的新文件(虽然它基于XML但不一样)。
我有以下XML结构:
<?xml version="1.0" encoding="UTF-8"?>
<log>
<published>2014-03-28T15:28:36.646Z</published>
<actor>
<objectType>person</objectType>
<id>e1b8948f-321e-78ca-d883-80500aae71b5</id>
<displayName>anonymized</displayName>
</actor>
<verb>update</verb>
<object>
<objectType>concept</objectType>
<id>a1ad6ace-c722-ffa9-f58e-b4169acdb4e3</id>
<content>time</content>
</object>
<target>
<objectType>conceptMap</objectType>
<id>4b8f69e3-2914-3a1a-454e-f4c157734bd1</id>
<displayName>my first concept map</displayName>
</target>
<generator>
<objectType>application</objectType>
<url>http://www.golabz.eu/content/go-lab-concept-mapper</url>
<id>c9933ad6-dd4a-6f71-ce84-fb1676ea3aac</id>
<displayName>ut.tools.conceptmapper</displayName>
</generator>
<provider>
<objectType>ils</objectType>
<url>http://graasp.epfl.ch/metawidget/1/b387b6f</url>
<id>10548c30-72bd-0bb3-33d1-9c748266de45</id>
<displayName>unnamed ils</displayName>
</provider>
</log>
这是应该执行此操作的方法(包括两个子方法):
public static void parseRecursive(Node node, Node parent, Node value) {
NodeList childs = node.getChildNodes();
int countChilds = childs.getLength();
int i = 0;
//<log> shouldn't be added as a node!
if (parent != null && !(parent.getNodeName().equals("log"))) {
if (!doubledItem.contains(parent)) {
value = toXes.createString(parent.getNodeName(), "");
doubledItem.add(parent);
System.out.println("Added ---" + parent + "--- to HashSet");
}
}
//iterate over all child elements
while (i < countChilds) {
Node child = childs.item(i);
//Proofs whether "#text" is the only child-element.
if (countChilds > 1) {
//System.err.println("Number of WHILE-passes: " + i);
parseRecursive(child, node, value);
} else {
//"published" and "verb" shouldn't be handled as if they were child elements of <log> but rather of <event>
if (parent != null && (node.getNodeName().equals("verb")|| node.getNodeName().equals("published"))){
toXes.createString(node.getNodeName(), child.getNodeValue());
//leave out the id-node
} else if (parent != null && !(node.getNodeName().equals("id"))) {
//in some passes the value is "null". What I want: it shouldn't be null but pass the value of the previous recursion without execute "createString" multiple times.
toXes.createNestedString2(node.getNodeName(), child.getNodeValue(), value);
}
}
++i;
}
}
//Appends the <string>-element to the <event>-element.
public static Node createString(String key, String value) {
System.out.println("KEY: " + key + " - VALUE: " + value);
//NodeList nl = eventElement.getElementsByTagName(key);
//if (nl == null) {
stringElement = doc.createElement("string");
// attributes of "string"-element in .xes - key
attr = doc.createAttribute("key");
attr.setValue(key);
stringElement.setAttributeNode(attr);
// attributes of "string"-element in .xes - value
attr = doc.createAttribute("value");
attr.setValue(value);
stringElement.setAttributeNode(attr);
eventElement.appendChild(stringElement);
//}
return stringElement;
}
//Appends the <string>-element to the parent element.
public static void createNestedString2(String key, String value, Node parent) {
Element stringElement = doc.createElement("string");
parent.appendChild(stringElement);
// attributes of "string"-element in .xes - key
attr = doc.createAttribute("key");
attr.setValue(key);
stringElement.setAttributeNode(attr);
// attributes of "string"-element in .xes - value
attr = doc.createAttribute("value");
attr.setValue(value);
stringElement.setAttributeNode(attr);
}
正如评论中所提到的,我试图实现由“createNestedString2”生成的Node应该只附加到实际的父节点,而不是只是在没有为每个父节点多次调用“createString”的任何地方。 有没有办法保存“createString”为多个递归传递生成的返回结果,而不是多次调用createString?
修改
预期产出:
<log xes.features="" xes.version="2.0">
<trace>
<event>
<string key="published" value="2014-03-28T15:28:36.646Z"/>
<string key="actor" value="">
<string key="objectType" value="person"/>
<string key="displayName" value="anonymized"/>
</string>
<string key="verb" value="update"/>
<string key="object" value="">
<string key="objectType" value="concept"/>
<string key="content" value="time"/>
</string>
<string key="target" value="">
<string key="objectType" value="conceptMap"/>
<string key="displayName" value="my first concept map"/>
</string>
<string key="generator" value="">
<string key="objectType" value="application"/>
<string key="url" value="http://www.golabz.eu/content/go-lab-concept-mapper"/>
<string key="displayName" value="ut.tools.conceptmapper"/>
</string>
<string key="provider" value="">
<string key="objectType" value="ils"/>
<string key="url" value="http://graasp.epfl.ch/metawidget/1/b387b6f"/>
<string key="displayName" value="unnamed ils"/>
</string>
</event>
</trace>
</log>
但输出如下:
<log xes.features="" xes.version="2.0">
<trace>
<event>
<string key="published" value="2014-03-28T15:28:36.646Z"/>
<string key="actor" value="">
<string key="objectType" value="person"/>
<NULLPOINTER-EXCEPTION, because "value" is null>
答案 0 :(得分:0)
不太好但是这个解决方法应该解决它:
public static void parseRecursive(Node node, Node parent, Node value) {
NodeList childs = node.getChildNodes();
int countChilds = childs.getLength();
int i = 0;
//<log> shouldn't be added as a node!
if (parent != null && !(parent.getNodeName().equals("log"))) {
if (!doubledItem.contains(parent)) {
value = toXes.createString(parent.getNodeName(), "");
doubledItem.add(parent);
map.putIfAbsent(parent.getNodeName(), value);
System.out.println("Added ---" + parent + "--- to HashSet");
}
}
//iterate over all child elements
while (i < countChilds) {
Node child = childs.item(i);
//Proofs whether "#text" is the only child-element.
if (countChilds > 1) {
//System.err.println("Number of WHILE-passes: " + i);
parseRecursive(child, node, value);
} else {
//"published" and "verb" shouldn't be handled as if they were child elements of <log> but rather of <event>
if (parent != null && (node.getNodeName().equals("verb")|| node.getNodeName().equals("published"))){
toXes.createString(node.getNodeName(), child.getNodeValue());
//leave out the id-node
} else if (parent != null && !(node.getNodeName().equals("id"))) {
//toXes.createNestedString(node.getNodeName(), child.getNodeValue(), "string");
toXes.createNestedString2(node.getNodeName(), child.getNodeValue(), map.get(parent.getNodeName()));
}
}
++i;
}
}