近况
又来水一篇博客了,事实上网上很多相关文章,我也没别人写的好,那为什么还要继续写呢
可能是我太需要一点收获支撑下去了,我需要成就感让我继续下去,但是现在的生活环境就很难感到充实
我需要去改变,我绝不接受苟且的生活,我要有意义有价值的活着
JAXB的基础使用
JAXB是操作XML文件的技术之一,相关的技术有Dom4J,Jdom,Dom,sax,JAXB
通过浏览几篇博客,我介绍一下自己对这些技术的粗浅理解吧
- Dom4j是主流的操作XML文件的方式,它是Jdom的升级版本,能读能写,它将XML文件一次性加载进内存进行处理
缺点自然也很明显,如果XML文件太大可能处理不了,不过我觉得大部分的场景都OK - Jdom和Dom4J都是基于Dom开发,而Dom是Jdk自带的库,这三个库都是将XML文件一次性加载进内存中操作
而sax库也是JDK自带的,它的特点是流式处理,边解析边处理,并不将XML文件一次性加载进内存
所以不会发生OOM的情况,但是sax只能读取数据,不能写入数据到XML文件中,
总体来看,sax适合处理那些XML文件特别大的场景,算是一种特殊场景,并不常用,但必不可少。 - JAXB也可以操作XML文件,能读能写,这项技术是javax包下的,属于正规军了,JAXB操作XML文件的方式是
对象映射,和hibernate操作数据库一样,通过将XML文件标签映射为对象或属性,内存中改变对象数据,再写成XML文件,非常容易使用
JAXB不好的一点在于,它是静态的,在读取XML文件之前,需要编写XML文件对应的实体类,在实际使用中可能适用于那些DOM结构比较简单的XML文件 - 总结
如果业务逻辑不复杂,DOM结构简单,使用JAXB,
如果逻辑复杂,有需要动态更改DOM结构,使用Dom4J
如果对内存资源要求高或XML文件太大,则使用stax(sax的升级版)
JAXB的小案例
Teacher和Student的实体类
//Teacher @Data @AllArgsConstructor @NoArgsConstructor @XmlRootElement(name = "teacher") @XmlAccessorOrder @XmlAccessorType(XmlAccessType.FIELD) public class Teacher { @XmlElement(name="tName") private String name; @XmlElement(name="tAge") private Integer age; @XmlElementWrapper(name = "students") private ArrayList<Student> children; } //Student @XmlAccessorOrder @XmlRootElement(name = "student") @XmlAccessorType(XmlAccessType.FIELD) @Data @AllArgsConstructor @NoArgsConstructor public class Student { @XmlAttribute private String createTime; @XmlElement(name = "sName") private String name; @XmlElement(name = "sAge") private Integer age; }
工具类
public class XSDFileUtils { private static StringBuilder buffer = new StringBuilder(); private static String prefix = "<xs:element"; private static String minOccurs = "minOccurs=\"1\" "; private static String minOccurs2 = "minOccurs=\"0\" "; private static String nillable = "nillable=\"false\" "; private static String nillable2 = "nillable=\"true\" "; private String desPath = null; public XSDFileUtils() { } public static void readFiles(String path, String despath) { File file = new File(path); if (file.isDirectory()) { String[] fl = file.list(); String[] var4 = fl; int var5 = fl.length; for(int var6 = 0; var6 < var5; ++var6) { String tempFile = var4[var6]; File f = new File(path + "\\" + tempFile); if (!f.isDirectory()) { changeContent(f, despath); } } } } public static void changeContent(File f, String despath) { try { InputStreamReader in = new InputStreamReader(new FileInputStream(f), "utf-8"); StringBuilder build = new StringBuilder(); BufferedReader reader = new BufferedReader(in); String content = null; String outpath; while((content = reader.readLine()) != null) { outpath = changeContent(content); build.append(outpath + "\n"); } if (despath == null) { despath = f.getParentFile().getPath(); } outpath = "E:\\hello"; String filepath = f.getPath().substring(f.getPath().lastIndexOf("\\") + 1); String temp = despath + File.separator + outpath.substring(outpath.lastIndexOf("\\") + 1); writeFile(build.toString(), temp, filepath); reader.close(); } catch (FileNotFoundException var9) { } catch (IOException var10) { } } public static String changeContent(String content) { String temp = content; if (content.trim().startsWith(prefix)) { if (content.indexOf("minOccurs=") < 0 && content.indexOf("nillable=") < 0) { } if (content.contains("minOccurs=\"0\"") && !content.contains("nillable=")) { String prefix2 = "minOccurs=\"0\""; String tempContent = content.replace(prefix2, ""); String end = tempContent.substring(tempContent.indexOf(prefix) + prefix.length() + 1); temp = tempContent.substring(0, tempContent.indexOf(prefix) + prefix.length() + 1) + minOccurs2 + nillable2 + end; } } return temp; } public static void writeFile(String content, String path, String fileName) { try { File files = new File(path, fileName); generalFile(files); BufferedWriter write = new BufferedWriter(new FileWriter(files)); write.write(content); write.close(); } catch (IOException var5) { } } public static void generalFile(File file) { try { if (!file.getParentFile().isDirectory()) { file.getParentFile().mkdirs(); } if (!file.exists()) { file.createNewFile(); } } catch (IOException var2) { } } public static void writeTableClassXSD(String xsdFileName, Class... clazz) throws JAXBException, IOException { JAXBContext jaxbContext = JAXBContext.newInstance(clazz); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty("jaxb.formatted.output", true); marshaller.setProperty("jaxb.encoding", "UTF-8"); marshaller.setProperty("jaxb.fragment", false); jaxbContext.generateSchema(new SchemaOutputResolver() { @Override public Result createOutput(String namespaceURI, String suggestedFileName) throws IOException { return new StreamResult(xsdFileName); } }); } public static void writeXML(Object obj, File path, Class... clazz) throws JAXBException, IOException, XMLStreamException { JAXBContext jaxbContext = JAXBContext.newInstance(clazz); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty("jaxb.formatted.output", true); marshaller.setProperty("jaxb.encoding", "UTF-8"); marshaller.setProperty("jaxb.fragment", false); marshaller.marshal(obj, path); } public static Object readXML(File path, Class... clazz) throws JAXBException { JAXBContext jctx = JAXBContext.newInstance(clazz); Unmarshaller unMarshaller = jctx.createUnmarshaller(); Object obj = unMarshaller.unmarshal(path); return obj; } }
测试类
public class XmlTest { public static void main(String[] args) throws JAXBException, IOException, XMLStreamException { String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); Student wanyi = new Student(date,"万一", 20); Student waner = new Student(date,"万二", 22); ArrayList<Student> students = new ArrayList<>(); students.add(wanyi); students.add(waner); Teacher wansan = new Teacher("万三", 24, students); //写出xml文件和xsd文件,xsd文件用于帮助xml解释器去解释某个xml文件的,可以理解为是读取xml文件的协议,规范 File outXmlFile = new File("C:\\Users\\Coco\\Desktop\\test.xml"); String outXsdFile = "C:\\Users\\Coco\\Desktop\\test.xsd"; XSDFileUtils.writeXML(wansan,outXmlFile,Teacher.class); XSDFileUtils.writeTableClassXSD(outXsdFile,Teacher.class); //读取xml文件 Teacher teacher = (Teacher) XSDFileUtils.readXML(outXmlFile, Teacher.class); System.out.println(teacher); } } //测试结果 //test.xml文件 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <teacher> <tName>万三</tName> <tAge>24</tAge> <students> <children createTime="2022-12-07"> <sName>万一</sName> <sAge>20</sAge> </children> <children createTime="2022-12-07"> <sName>万二</sName> <sAge>22</sAge> </children> </students> </teacher> //xsd即是XML Schema,描述了XML文档的结构,xsd文件是验证某个xml文件是否符合其要求的 //test.xsd文件 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="teacher" type="teacher"/> <xs:complexType name="teacher"> <xs:all> <xs:element name="tName" type="xs:string" minOccurs="0"/> <xs:element name="tAge" type="xs:int" minOccurs="0"/> <xs:element name="students" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="children" type="student" nillable="true" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:all> </xs:complexType> <xs:complexType name="student"> <xs:all> <xs:element name="sName" type="xs:string" minOccurs="0"/> <xs:element name="sAge" type="xs:int" minOccurs="0"/> </xs:all> <xs:attribute name="createTime" type="xs:string"/> </xs:complexType> </xs:schema>
文章推荐