保持整个递归的价值

时间:2014-11-12 14:55:37

标签: java xml dom recursion

问题描述

我想修改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>

1 个答案:

答案 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;
    }
}