使用Java将平面文件记录转换为XML

3

我有一个场景,员工记录以平面文件的形式编写,类似于:

flatFile.txt
============
1|name1|dept1|10000
2|name2|dept2|12000
3|name3|dept3|9500
....
....

现在我想要读取这个平面文件,将上述员工记录转换成一些新的XML文件,最终我应该拥有包含以下数据的XML文件:
<EMPLOYEES>
    <EMPLOYEE>
        <ID>1</ID>
        <NAME>name1</NAME>
        <DEPARTMENT>dept1</DEPARTMENT>
        <SALARY>10000</SALARY>
         </EMPLOYEE>
    <EMPLOYEE>
        <ID>2</ID>
        <NAME>name2</NAME>
        <DEPARTMENT>dept2</DEPARTMENT>
        <SALARY>12000</SALARY>
         </EMPLOYEE>
         ...
         ...
</EMPLOYEES>

现在要实现这个概念,我需要注意数据的验证,例如:
  1. id和salary应该是数字
  2. 名字长度应该小于20
  3. 一个平面文件的单行应包含以上4个字段
如果任何一项验证失败,则需要将其反映在xml文件中,并附带错误行号,类似于:
<NAME type="Error" Line="2"></NAME> (name length is greater than 20 in 2nd record of a flat file)

或者

<EMPLOYEE type="Error" Line="1"></EMPLOYEE> (first record doesn't contains enough fields)

现在的应用程序需要以组件化、可替换的方式进行设计。例如,应该可以基于分隔符将解析输入文件的解析器替换为将其解析为固定长度的另一个解析器。
因此,我需要以分层的方式设计这个概念。
Parsing -> Validation -> Output Generation.

为了实现这个概念,我想出了以下方法:

  1. 使用BufferedReader读取文件中的所有记录,并使用StringTokenizer将其进行分词。
  2. 为每个记录初始化一个雇员对象,然后将它们添加到某个集合(List)中。
  3. 将错误(字段不匹配或任何其他验证失败)保存在Map<中。
  4. 使用一些XML Builder API(不清楚哪个最好)将列表写入或Marshal到xml中。

有没有人能给我更好的建议或任何实现提示?


使用像ATL这样的(text2text)转换语言。 - zeller
@zeller,您能否详细说明一下您的评论? - Nirmal
你的概念不具备可扩展性,考虑一个拥有500k条记录的XML文件。你应该考虑流式处理(取决于你的需求)... - home
1
我建议您将XStream作为库(用于点d)进行研究。这是2分钟教程:http://xstream.codehaus.org/tutorial.html - hovanessyan
我赞同使用XStream来完成这个任务。 - Tobb
@home,你能告诉我这里的streaming是什么意思吗? - Nirmal
2个回答

3
我会使用JDK/JRE中可用的库来完成以下任务,这些库从Java SE 6开始提供。
  1. 创建一个StAX (JSR-173) XMLStreamWriter来将XML内容输出到文件。
  2. 使用XMLStreamWriter编写根元素。
  3. 读取输入的下一行。
  4. 将其转换为Employee对象。
  5. 使用JAXB (JSR-222)将对象编组到XMLStreamWriter中。
  6. 如果还有另一行,请重复步骤3。
  7. 使用XMLStreamWriter结束文档。

更新

有不同的选项来执行实际的验证,下面我将演示如何在对象模型中表示结果信息,JAXB实现可以使用它来产生所需的结果。

员工

package forum12446506;

import javax.xml.bind.annotation.*;

@XmlRootElement(name="EMPLOYEE")
public class Employee {

    @XmlAttribute(name="Line")
    Integer line;

    @XmlAttribute
    String type;

    @XmlElement(name="ID")
    Value id;

    @XmlElement(name="NAME")
    Value name;

    @XmlElement(name="DEPARTMENT")
    Value department;

    @XmlElement(name="SALARY")
    Value salary;

    public Employee() {
    }

    public Employee(int line, String type) {
        this.line = line;
        this.type = type;
    }

}

价值

package forum12446506;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Value {

    @XmlAttribute(name="Line")
    Integer line;

    @XmlAttribute
    String type;

    @XmlValue
    String value;

    public Value() {
    }

    public Value(Integer line, String type, String value) {
        this.line = line;
        this.type = type;
        this.value = value;
    }

}

输出

<EMPLOYEE>
    <ID>1</ID>
    <NAME type="Error" Line="1"/>
</EMPLOYEE>

<EMPLOYEE type="Error" Line="2"/>

采用这种方法,我应该在哪里放置验证和错误相关的XML条目? - Nirmal
@Nirmal - 我已经更新了我的答案,以展示如何完成这个任务。 - bdoughan

1
请阅读下面提到的教程链接,了解如何将平面文件转换为XML,并请完整阅读,此外,提供此教程的原因是让您意识到没有神奇的方法可以直接将平面文件转换为XML但是确实有正确的方法来做到这一点.....

http://cafeconleche.org/books/xmljava/chapters/ch04.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接