【问题标题】:Convert a Tree like List of Strings to xml [closed]将类似字符串列表的树转换为 xml [关闭]
【发布时间】:2014-10-01 12:19:15
【问题描述】:

我需要转换存储在 ArrayList 中的这些类型的字符串:

Alpha.Beta.Com.
Alpa.Xeta.Hash.
Alpha.Eta.Dot.
Alpha.Eta.Comma.
Alpha.Eta.Dollar.
Alpha.Xeta.Tilde
Alpha.Beta.Com.Xeta.

这里是 Alpha.Beta.Com。将有 Xeta 作为孩子,但 Xeta 不能在此对象中将 Hash 和 Tilde 作为孩子。 只是,Alpha.Xeta 对象会将哈希和波浪号作为子对象

这些字符串就像树状结构(n 级),这意味着,Alpha 有 Beta、Xeta 和 Eta 作为子级。 此外,Beta 有 Com, Xeta 有哈希和波浪号, Eta 有 Comma,Dollar 和 Dot 作为孩子。

我们需要使用java程序识别每个父子节点,然后将其构建为XML。

【问题讨论】:

  • 可能的答案太多,或者对于这种格式来说,好的答案太长了。请添加详细信息以缩小答案范围或隔离可以在几段中回答的问题。
  • 您好 Guido,感谢您的回复,您能否回答或发送此问题的参考链接。

标签: java xml data-structures tree logic


【解决方案1】:

检查一下:

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class StringsToXmlConverter {

    private static final String SEPARTOR = "\\.";

    List<String> list;

    Map<String, XmlElement> elements = new HashMap<String,XmlElement>();

    public StringsToXmlConverter(List<String> list) {
        this.list = list;
    }

    public String getXml() {
        for (String xmlPaths: list) {
            String[] splitedElements = xmlPaths.split(SEPARTOR);
            XmlElement parent = null;
            for (String elem : splitedElements) {
                XmlElement currentElem = null;
                if (elements.containsKey(elem)) {
                    currentElem = elements.get(elem);
                    if (parent != null) {
                        addChild(parent, currentElem);
                    } 
                } else {
                    currentElem = createNewElement(parent, elem);
                    elements.put(elem, currentElem);
                }
                parent = currentElem;
            }
        }

        return buildXml().toString();
    }

    private void addChild(XmlElement parent, XmlElement currentElem) {
        currentElem.parent = parent;
        parent.childs.add(currentElem);
    }

    private XmlElement createNewElement(XmlElement parent, String name) {
        XmlElement currentElem;
        currentElem = new XmlElement();
        currentElem.name = name;
        if (parent != null) {
            addChild(parent, currentElem);
        }
        return currentElem;
    }

    private StringBuilder buildXml() {
        StringBuilder xml = new StringBuilder();
        for(XmlElement elem : elements.values()) {
            if (elem.parent == null) {
                xml.append(elem.toXml());
            }
        }
        return xml;
    }

    private class XmlElement {
        String name;
        Set<XmlElement> childs = new HashSet<XmlElement>();
        XmlElement parent = null;
        boolean isPrinted = false;

        private Set<XmlElement> getNoPrintedChilds() {
           Set<XmlElement> notPrintedChilds = new HashSet<XmlElement>();
           Iterator<XmlElement> iterator = childs.iterator();
           while(iterator.hasNext()) {
               XmlElement node = iterator.next();
               if (!node.isPrinted) {
                   notPrintedChilds.add(node);
               }
           }
           return notPrintedChilds;
        }

        public String toXml() {
           StringBuilder xml = new StringBuilder();
           if (!isPrinted) {
               xml.append("<" + name); 
               if (getNoPrintedChilds().isEmpty()) {
                xml.append("/>");
               } else {
                   xml.append(">");
                   for (XmlElement elem : getNoPrintedChilds()) {
                       xml.append(elem.toXml());
                   }
                   xml.append("</" + name + ">");
               }
           }
           isPrinted = true;
           return xml.toString();
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + getOuterType().hashCode();
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            XmlElement other = (XmlElement) obj;
            if (!getOuterType().equals(other.getOuterType()))
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }
        private StringsToXmlConverter getOuterType() {
            return StringsToXmlConverter.this;
        }
    }

    public static void main(String[] args) {
        List<String> list= Arrays.asList("Alpha.Beta.Com", 
                                         "Alpha.Xeta.Hash", 
                                         "Alpha.Eta.Dot",
                                         "Alpha.Eta.Comma",
                                         "Alpha.Eta.Dollar",
                                         "Alpha.Xeta.Tilde");
        StringsToXmlConverter converter = new StringsToXmlConverter(list);
        System.out.println(converter.getXml());
    }


}

【讨论】:

  • 是否有任何限制,我在第 79 行和第 80 行遇到 stackoverflow 错误,它们是:79) for (XmlElement elem :childs) { 80) xml.append(elem.toXml( ));
  • 你得到什么异常?您使用的是相同的测试数据还是其他数据?
  • 更正了,实际上在我的分隔字符串中,一些点分隔字符是相同的,这导致了该异常。
  • Alpha.Eta.Dollar.Xeta。将 Tilde 和 Hash 作为 Alpha.Eta.Dollar.Xeta 的孩子返回,请在这方面提供帮助。
  • 请查看更新后的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 2017-11-10
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 2019-08-17
相关资源
最近更新 更多