从excel中读取信息并生成XML结构的文档
有这样一个需求,一个excel文件,里面描述了一个xml结构的文档。 我们需要做一个工具,读取excel内容并生成该结构的文件。 以何种形式保存该信息是本文讨论的关键。
举个例子,excel包含这些信息, 顺序和Level是决定最终样式的重要数据:
Level:1, company
Level:2, developer
Level:3, name, DevA
Level:3, age, 25
Level:2, tester
Level:3, name, QAB
生成后样式:
<company>
<developer>
<name>DevA</name>
<age>25</age>
</developer>
<tester>
<name>QAB</name>
<age>22</age>
</tester>
</company>
[前期封装]
我们可以视excel每一行数据(即xml中的每个节点)为一个对象,假设excel中只包含节点名和值信息,创建这样一个简单的对象。
public class Element {
private int level;
private String tagName;
private String value;
private ArrayList<Element> childElements = new ArrayList<Element>();
public String getTagName() {
return tagName;
}
public void setTagName(String tagName) {
this.tagName = tagName;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public void addChildElement(Element e) {
childElements.add(e);
}
public List getChildElements() {
return childElements;
}
}
[读取Elements]
我们可以逐行读取Element,可是新读到的Element只包含Level信息以及其自身的内容。我们将以何种方式存储读取过的对象呢?而且我们需要将读取到的节点对象,与当前的节点形成正确的父子关系。
若仅仅用,读一行,加为子节点的手段。我们加developer为company的子节点, developer再将name, age加为自己的子节点。可是当我们读到tester这行时,它的谁的子节点,如果没有好的结构保存已读出的数据,我们将很难判断。
其实,我们不难发现,xml结构的数据,我们可以用树图来表示。
保存树的方法有很多,由于本人算法数据结构学的都不咋地,就用最简单的HashMap来保存。
呵呵,HashMap其实也是可以保存树结构的,尽管傻些,不过针对这个问题,还挺好用。
我们先来探讨用什么作为HashMap的Key。值很简单,则为各个节点对象。
company的key可以简单的以0表示,若有一个子节点则在后面加0,若该节点又有一个子节点则最后的数字加1,注意这里就不是加一位了,以此类推。
用图表示如下:
若tester下面还有子节点则,标位为011。
下面我们就可以遍历excel文件中的内容,并保存在HashMap中。
先设一个rootElement,初始position为"0"。
Element rootElement;
String position = "0"
由于实际项目并不是java写的,个别处用伪代码
while (excel中有数据) {
// 读取一条数据,并生成Element
Element currElement = readElement(execelFile, line)
// 获取Level等级
level = currElement.getLevel();
// 若 level 为 1,说明此Element为root
If (level == 1) {
rootElement = currElement;
} else {
// 若Level大于当前position的长度,则视为新读到的Element是当前position节点的子节点
if (level > position.length) {
Element paramElement = elementMap.get(position);
paramElement.addChildElement(currElement);
position = position + "0";
// 若Level等于当前position长度,则视为与当前position节点有相同的父节点。
} else if (level == position.length) {
Element paramElement = elementMap.get(position.subString(0, level - 1));
paramElement.addChildElement(currElement);
position = position.subString(0, position.length - 1)
+ (Integer.parseInt(position.subString(position.length - 1))) + 1);
// 若Level小于当前position长度,则视为跳回到Level处,与其有相同的父节点。 Position为跳回Level处再加1.
} else {
Element paramElement = elementMap.get(position.subString(0, level - 1));
paramElement.addChildElement(currElement);
String newPosition = position.subString(0, level));
position = newPosition.subString(0, newPosition.length - 1)
+ (Integer.parseInt(newPosition.subString(newPositionion.length - 1))) + 1);
}
}
// 将当前的Element加入到HashMap中
elementMap.put(position, currElement);
line++;
}
以上代码,我们通过HashMap作为树结构的保存方式,生成了所有Elements的父子关系。我们可以通过获取rootElement的所有子节点进行验证。
后面的工作,我们就可以从rootElements开始遍历子节点,去生成文件了,由于不是本文重点,略去。
Hope it can relax your eyes : )