在插件开发中,遇到需要持久化对象或者保存配置信息的情况,就需要读写xml文件。
我们以在WorkBook对象中扩展IOFileAttrMark属性为例子:
一个完全空的模板,其xml文件(即cpt文件)大致为下面的样子
<?xml version="1.0" encoding="UTF-8"?> <WorkBook xmlVersion="20151125" releaseVersion="8.0.0"> <Report class="com.fr.report.worksheet.WorkSheet" name="sheet1"> <ReportPageAttr> <HR/> <FR/> <HC/> <FC/> </ReportPageAttr> <ColumnPrivilegeControl/> <RowPrivilegeControl/> <RowHeight defaultValue="723900"> <![CDATA[723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900]]></RowHeight> <ColumnWidth defaultValue="2743200"> <![CDATA[2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200]]></ColumnWidth> <CellElementList> <C c="0" r="0"> <PrivilegeControl/> <Expand/> </C> </CellElementList> <ReportAttrSet> <ReportSettings headerHeight="0" footerHeight="0"> <PaperSetting/> </ReportSettings> </ReportAttrSet> <PrivilegeControl/> </Report> <StyleList/> <DesignerVersion DesignerVersion="IAA"/> <PreviewType PreviewType="0"/> </WorkBook> |
我们略去所有空的和不重要的节点,大概就是这样
<?xml version="1.0" encoding="UTF-8"?> <WorkBook xmlVersion="20151125" releaseVersion="8.0.0"> <Report class="com.fr.report.worksheet.WorkSheet" name="sheet1"> <DesignerVersion DesignerVersion="IAA"/> <PreviewType PreviewType="0"/> </WorkBook> |
然后我们使用给模板增加一个额外的属性的插件,简单的打开一个额外属性设计界面并保存,可以看到模板的xml文件(忽略掉不重要节点后)大概是这样的
<?xml version="1.0" encoding="UTF-8"?> <WorkBook xmlVersion="20151125" releaseVersion="8.0.0"> <Report class="com.fr.report.worksheet.WorkSheet" name="sheet1"> <DesignerVersion DesignerVersion="IAA"/> <PreviewType PreviewType="0"/> <SomeConfig class="com.fr.plugin.io.file.SomeConfig"> <Attr status="100"/> </SomeConfig> </WorkBook> |
写入SomeConfig节点的方式,就是在writeXML的时候,调用了
public void writeConfig(XMLPrintWriter writer, SomeConfig config) { GeneralXMLTools.writeXMLable(writer, config, "SomeConfig"); } |
同样的,在读取xml的时候,也就是把配置文件转化为WorkBook对象时,在读取SomeConfig节点的时候,是这样的
protected void readConfig(XMLableReader reader) { if (reader.isChildNode()) { String tagName = reader.getTagName(); if (tagName.equals("SomeConfig")) { SomeConfig config = new SomeConfig(); reader.readXMLObject(config); this.addAttrMark(config); } } } |
在调用了reader.readXMLObject(config);这句之后,就将xml中设置的属性赋值给了config对象了。
上面我们看到了再WorkBook中读写其属性SomeConfig的的方法,这一节我们再看一下SomeConfig本身的属性如何去读写。
public class SomeConfig extends AbstractIOFileAttrMark { private int status = 0; public SomeConfig() { } public SomeConfig(int status) { this.status = status; } public int getStatus() { return status; } @Override public String xmlTag() { return "SomeConfig"; } @Override public SomeConfig clone() { SomeConfig cloned = (SomeConfig) super.clone(); cloned.status = status; return cloned; } @Override public void readXML(XMLableReader reader) { if (reader.isChildNode()) { String tagName = reader.getTagName(); if ("Attr".equals(tagName)) { status = reader.getAttrAsInt("status", 0); } } } @Override public void writeXML(XMLPrintWriter writer) { writer.startTAG("Attr"); writer.attr("status", status); writer.end(); } } |
从SomeConfig的源码中可以看到,这个类是实现了XMLable接口的(所有需要读写xml文件的对象,都需要实现XMLable接口),此外XMLPrintWriter的startTAG和XMLPrintWriter的end方法必须是成对出现的。通过这个writeXML方法,写出来的xml文件就是SomeConfig标签内的Attr标签中的内容
<SomeConfig class="com.fr.plugin.io.file.SomeConfig"> <Attr status="100"/> </SomeConfig> |
同样的,读xml的时候,也是通过判断是否读到了Attr节点,来进行属性读取。