如何在java中创建xml文件
我正在创建创建文档的软件(确切地说是贝叶斯网络图),这些文档需要以XML格式保存 我知道如何创建XML文件,但我还没有决定如何组织代码 目前,我计划让每个对象(即顶点或边)都有一个名为getXML()的函数(它们可能会实现一个接口,以便以后可以对其进行扩展)。getXML()将返回一个包含该对象的XML的字符串 还有一个对象将收集所有这些XML字符串并将它们放在一起,然后输出一个XML文件如何在java中创建xml文件,java,design-patterns,Java,Design Patterns,我正在创建创建文档的软件(确切地说是贝叶斯网络图),这些文档需要以XML格式保存 我知道如何创建XML文件,但我还没有决定如何组织代码 目前,我计划让每个对象(即顶点或边)都有一个名为getXML()的函数(它们可能会实现一个接口,以便以后可以对其进行扩展)。getXML()将返回一个包含该对象的XML的字符串 还有一个对象将收集所有这些XML字符串并将它们放在一起,然后输出一个XML文件 出于某种原因,我认为这似乎有点混乱,你建议怎么做?这似乎并不不合理。我会让你的贝叶斯网络图对象遍历每个顶点
出于某种原因,我认为这似乎有点混乱,你建议怎么做?这似乎并不不合理。我会让你的贝叶斯网络图对象遍历每个顶点/边
Model model = new Model();
View view = new XMLView(model); // ok
您的建议打破了这一界限——简言之,您的模型应该就是这样,并且不应该了解XML序列化
在另一个对象中执行XML序列化要好得多。我建议使用XMLBeans。
它是一个工具/框架,可以使用解析器和格式化程序bean生成Jar文件。您不需要接触单个w3c类。
但这不是我推荐它的原因 XML格式的问题是,如果格式更改,则需要更改代码。 那么,如果你错过了一个改变呢?直到运行时你才会知道 XMLBeans将格式更改转移到编译时出现问题的地方。 这意味着您要为格式(XSD)定义一个契约,使用XMLBeans来构建解析器/格式化程序/验证器。其余的由IDE决定
基本上,您对设计的想法听起来像XMLBeans所做的。另一个建议:使用
XMLEncoder
并为非bean样式的对象编写必要的PersistenceDelegate
类;e、 g
static class FilePersistenceDelegate extends PersistenceDelegate {
protected Expression instantiate(Object oldInstance, Encoder out) {
File file = (File)oldInstance;
return new Expression(oldInstance, oldInstance.getClass(), "new", new Object[]{ file.getPath() });
}
}
执行实际编码的my代码将执行以下操作:
XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(file))));
for (Map.Entry<Class<?>, PersistenceDelegate> entry : MY_DELEGATES.entrySet()) {
// Add any custom persistence delegates written.
encoder.setPersistenceDelegate(entry.getKey(), entry.getValue());
}
encoder.writeObject(object);
encoder.close();
if (encoder.getException() != null) {
// Encoding failed.
}
XMLEncoder编码器=新的XMLEncoder(新的BufferedOutputStream(新的GZIPOutputStream(新的文件)));
对于(Map.Entry您必须使用Java吗?Scala包含隐式类型转换,允许您将模型对象隐式转换为您选择的视图表示形式。它还与Java完全兼容。例如:
def printData(obj: DataObject, os: OutputStream) = {
val view: ViewRepresentation = obj //note implicit conversion
view.printTo(os)
}
您有一个特征
(即接口
)
和隐式转换:
implicit def dataobj2xmlviewrep(obj: DataObject): ViewRepresentation = {
new XmlViewRepresentation(obj)
}
您只需对定制的XML表示进行编码。哦,是的,它在该语言中具有本机XML支持除了其他人提供的选项外,您还可以尝试JAXB和StAX:
- 您可以使用JAXB将对象映射到XML模式,以便神奇地输入和输出XML文档
- 您可以使用StAX以更基本的方式读取和写入XML文档,以满足您的低级需求
这两个选项的美妙之处在于,它们作为Java(JAXP)的一部分提供,而且它们似乎工作得很好,当然,除非有更好的选项存在!您的第一个建议是访问者模式吗?不完全是。访问者模式是一个双重委托,我不确定它是否真的需要这种复杂性,我假设您的意思是“不应该知道…”然后如何管理另一个对象关于(比如)顶点对象的知识,并在XML中呈现。要实现这一点,它不需要知道顶点对象的细节吗?@Brian Agnew我认为“另一个对象”知道域对象很好,就像一个视图一样(如@dfa的回答)了解有关域对象的信息。这并没有破坏SRP。@brian-是的,这是我一直不喜欢Visitor之类的东西:被调用的类需要知道调用方的详细信息。我晚上睡觉的时候会清楚区分数据类和行为类。我知道你从SRP得到了什么。我不确信的是顶点对象(比如)必须公开其内部工作,以便由第三方序列化。我的选择是让每个对象都知道如何序列化/反序列化自己。在我看来,这似乎是一个对象能够做到的合理做法。我知道这违反了SRP,但是,一个体面的toString()方法不是吗?(对不起,这不是争论,但是…)为什么要否决这一点?这是一种合法的方法,它通过使用委托将模型与XML表示完全分离。这是一个毫无意义的Scala插件!它必须是Java,不是个人项目,规范要求Java
trait ViewRepresentation {
def printTo(os: OutputStream)
}
implicit def dataobj2xmlviewrep(obj: DataObject): ViewRepresentation = {
new XmlViewRepresentation(obj)
}