Dom4j工具实现xml导入导出
当时需要的是一个题目的导入导出,但是要求的xml形式。
项目是前后分离的,这里是后端的代码讲解。
**
1. 导入
**
要导入的题目文件xml,在item标签内存着我们要读取的题目信息。
文件内可能有多个题目,下面举例,一个题目的xml。
<?xml version="1.0" encoding="UTF-8"?>
<fps version="1.2" url="https://githlemset/">
<generator name="HUSTOJ" url="httoj/"/>
<item>
<title><![CDATA[ 求两数之和 计算a+b]]></title>
<time_limit unit="s"><![CDATA[1]]></time_limit>
<memory_limit unit="mb"><![CDATA[10]]></memory_limit>
<description><![CDATA[<p style="margin-left:0in;">
从键盘上输入两个数据a和b,计算a和b之和并输出
</p>
<p style="margin-left:0in;">
(有输入,有输出)
</p>
<p>
<br />
</p>]]></description>
<input><![CDATA[<p>
两个整数 a,b (0<=a,b<=100)
</p>]]></input>
<output><![CDATA[<p>
输出 a+b的值
</p>]]></output>
<sample_input><![CDATA[1 2]]></sample_input>
<sample_output><![CDATA[3]]></sample_output>
<test_input><![CDATA[6 13
]]></test_input>
<test_output><![CDATA[19
]]></test_output>
<hint><![CDATA[<p>
Q: Where are the input and the output? A: Your program shall always <span>read input from stdin (Standard Input) and write output to stdout (Standard Output)</span>. For example, you can use 'scanf' in C or 'cin' in C++ to read from stdin, and use 'printf' in C or 'cout' in C++ to write to stdout. You <span>shall not output any extra data</span> to standard output other than that required by the problem, otherwise you will get a "Wrong Answer". User programs are not allowed to open and read from/write to files. You will get a "Runtime Error" or a "Wrong Answer" if you try to do so. Here is a sample solution for problem 1000 using C++/G++:
</p>
<pre>#include <iostream>
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
cout << a+b << endl;
return 0;
}</pre>
<p>
It's important that the return type of main() must be int when you use G++/GCC,or you may get compile error. Here is a sample solution for problem 1000 using C/GCC:
</p>
<pre>#include <stdio.h>
int main()
{
int a,b;
scanf("%d %d",&a, &b);
printf("%d\n",a+b);
return 0;
}</pre>
<p>
Here is a sample solution for problem 1000 using PASCAL:
</p>
<pre>program p1000(Input,Output);
var
a,b:Integer;
begin
Readln(a,b);
Writeln(a+b);
end.</pre>
<p>
Here is a sample solution for problem 1000 using JAVA: Now java compiler is jdk 1.5, next is program for 1000
</p>
<pre>import java.io.*;
import java.util.*;
public class Main
{
public static void main(String args[]) throws Exception
{
Scanner cin=new Scanner(System.in);
int a=cin.nextInt();int b=cin.nextInt();
System.out.println(a+b);
}
}</pre>
<p>
Old program for jdk 1.4
</p>
<pre>import java.io.*;
import java.util.*;
public class Main
{
public static void main (String args[]) throws Exception
{
BufferedReader stdin =
new BufferedReader(
new InputStreamReader(System.in));
String line = stdin.readLine();
StringTokenizer st = new StringTokenizer(line);
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
System.out.println(a+b);
}
}</pre>]]></hint>
<source><![CDATA[POJ]]></source>
<solution language="C++"><![CDATA[#include <iostream>
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
cout << a+b << endl;
return 0;
}]]></solution>
</item>
</fps>
直接上代码。(item内的标签名,对应着Bean的属性名)
public Boolean uploadProblem(MultipartFile file) throws IOException, DocumentException {
List<Problem> problemList=new ArrayList<>();
SAXReader reader = new SAXReader();
Document document = reader.read(file.getInputStream());
Element root = document.getRootElement();
//取出所有的root节点
List<Element> elements = root.elements("item");
//遍历所有的item
for (int i = 0; i < elements.size(); i++) {
Element element = elements.get(i);
List<Element> elements1 = element.elements();
Problem problem = new Problem();
HashMap<String,String> problemMap=new HashMap<>();
//取出item内标签 将标签名和标签内容对应到Map的<K,V>
elements1.forEach(item-> {
problemMap.put(item.getName(),item.getText());
});
//将map数据转到Bean中
BeanUtil.copyProperties(problemMap,problem);
problemList.add(problem);
}
this.saveBatch(problemList);
return Boolean.TRUE;
}
**
2.导出
**
controller部分代码
private Result<Object> export(@RequestBody List<Long> problemId, HttpServletResponse response) throws IOException {
problemService.export(problemId, response.getOutputStream());
String fileName = "problem";
try {
fileName = java.net.URLEncoder.encode(fileName, "utf-8");// IE11 浏览器
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
response.setContentType("multipart/form-data");
return Res.ok();
}
实现层代码
public Boolean export(List<Long> problemId, OutputStream outputStream) throws IOException {
List<Problem> problemList=new ArrayList<>();
problemId.forEach(item-> {
Problem problem = this.getById(item);
problemList.add(problem);
});
//创建文件
Document document= DocumentHelper.createDocument();
//新建一个标签
Element fps=document.addElement("fps");
//标签内赋值
fps.addAttribute("version","1.5");
fps.addAttribute("url","https://githuset/");
Element generator = fps.addElement("generator");
generator.addAttribute("name","HUSTOJ");
generator.addAttribute("url","https://githtoj/");
problemList.forEach(da->{
Element item = fps.addElement("item");
//添加子标签
Element title = item.addElement("title");。
//子标签内复值(下面的重复)
title.setText(da.getTitle());
Element timeLimit = item.addElement("time_limit");
timeLimit.setText(String.valueOf(da.getTimeLimit()));
Element memoryLimit = item.addElement("memory_limit");
memoryLimit.setText(String.valueOf(da.getMemoryLimit()));
Element description = item.addElement("description");
description.setText(da.getDescription());
Element input = item.addElement("input");
input.setText(da.getInput());
Element output = item.addElement("output");
output.setText(da.getOutput());
Element sampleInput = item.addElement("sample_input");
sampleInput.setText(da.getSampleInput());
Element sampleOutput = item.addElement("sample_output");
sampleOutput.setText(da.getSampleOutput());
Element hint = item.addElement("hint");
hint.setText(da.getHint());
Element source = item.addElement("source");
source.setText(da.getSource());
});
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
File file=new File("problem.xml");
//写入流和文件格式
XMLWriter writer=new XMLWriter(outputStream, format);
//特殊字符不被转译
writer.setEscapeText(false);
//写入文件
writer.write(document);
writer.close();
return Boolean.TRUE;
}