我正在使用 Java 后端来创建传递给浏览器的 XML 字符串。目前我正在使用简单的字符串操作来生成这个 XML。我是否必须在 Java 中使用一些 XML 库来生成 XML 字符串?与我需要的相比,我发现这些库很难使用。
11 回答
这不是必需的,但可取的。但是,如果字符串操作对您有用,那就去做吧!在很多情况下,可以手动安全地构建小的或简单的 XML 文本。
请注意,创建 XML 文本比看起来要难。以下是我会考虑的一些标准:
- 第一:您对进入 xml 的信息有多少控制权?
你对源数据的控制越少,你就越有可能遇到麻烦,图书馆就变得越有利。例如: (a) 你能保证元素名称永远不会在名称中包含非法字符吗?(b) 属性内容中的引号如何?它们会发生吗,你正在处理它们吗?(c) 数据是否包含任何可能需要编码为实体的内容(例如通常需要输出为<的小于);你做对了吗?
- 第二,可维护性:构建 XML 的代码是否易于其他人理解?
您可能不想终生被代码卡住。我曾使用过手动构建 XML 的二手 C++ 代码,但它可能令人惊讶地晦涩难懂。当然,如果这是您的个人项目,那么您不必担心“其他”:将上面的“一年”替换为“其他”。
我不会担心性能。如果您的 XML 足够简单以至于您可以手写它,那么库中的任何开销都可能毫无意义。当然,您的情况可能会有所不同,但您应该先测量以证明这一点。
最后,是的;如果足够简单,您可以手动构建 XML 文本;但不知道可用的库可能不是正确的原因。
现代 XML 库是一个非常强大的工具,但它也可能令人生畏。但是,学习 XML 库的基本要素并不难,而且非常方便;除其他外,这几乎是当今就业市场的必需品。在您掌握基本要素之前,不要被命名空间、模式和其他更高级的功能所困扰。
祝你好运。
XML 很难。解析自己是一个坏主意,自己生成内容甚至是一个更糟糕的主意。查看 Xml 1.1 规范。
您必须处理诸如正确的编码、属性编码(例如,产生无效的 xml)、正确的 CDATA 转义、UTF 编码、自定义 DTD 实体之类的事情,而无需将 xml 名称空间与默认/空名称空间、名称空间属性混合在一起, ETC。
学习一个工具包,有很多可用的。
我认为自定义字符串操作很好,但您必须记住两件事:
- 您的代码不如库成熟。在您的计划中分配时间来处理弹出的错误。
- 当 xml 开始增长时(在性能和易用性方面),您的方法可能无法像第 3 方库那样扩展。
我知道一个代码库,它对 xml 输出使用自定义字符串操作(以及用于输入的第 3 方库)。一开始还不错,但过了一段时间就变成了真正的麻烦。
是的,使用图书馆。
有人花时间和精力来创造通常比你能想出的更好的东西。字符串操作用于发送回单个节点,但是一旦您开始需要操作 DOM 或使用 XPath 查询,该库将拯救您。
如果不使用库,您可能会生成或解析格式不正确的数据,这种情况迟早会发生。出于同样的原因document.write
,在 XHTML 中不允许使用,您不应该将 XML 标记写为字符串。
是的。
跳过必要的工具是没有意义的:即使编写 xml 也很重要,因为必须避开那些 & 和 lts,更不用说命名空间绑定(如果需要)。最后,库通常不仅可以更可靠而且更有效地读取和写入 xml(尤其是对于 Java)。
但是,如果它们看起来过于复杂,您可能一直在寻找错误的工具。使用 JAXB 或 XStream 进行数据绑定很简单;但对于简单直接的 XML 输出,我使用StaxMate。它实际上可以通过多种方式简化任务(自动关闭开始标签,如果需要,编写命名空间声明等)。
否 - 如果您可以自己解析它(就像您正在做的那样),并且它会根据您的需要进行扩展,那么您不需要任何库。
只需确保满足您未来的需求 - 使用库更好地完成复杂的 xml 创建 - 其中一些也有非常简单的风格。
您不必使用库来解析 XML,但请查看这个问题
在重新发明轮子之前应该考虑什么?
在您开始编写自己的代码来解析/生成 xml 之前。
我唯一一次在生产代码中做这样的事情是当我和一位同事构建了一个预处理器,以便我们可以将来自其他文件的 XML 片段嵌入到更大的 XML 中。在加载时,我们将首先解析这些嵌入(XML 注释字符串中的文件引用)并将它们替换为它们引用的实际片段。然后我们会将组合结果传递给 XML Parser。
不 - 特别是对于生成(我不太倾向于解析,因为输入文本总是会让你感到惊讶)。我认为这很好 - 但是如果您发现自己花费超过几分钟来维护自己的代码,请准备好转向库。
我不认为使用JDK附带的DOM XML API很难,创建元素节点,属性等很容易......然后很容易将字符串转换为DOM文档或将DOM文档转换为字符串
在谷歌从西班牙找到的第一页(西班牙 XML 示例):
public String DOM2String(Document doc)
{
TransformerFactory transformerFactory =TransformerFactory.newInstance();
Transformer transformer = null;
try{
transformer = transformerFactory.newTransformer();
}catch (javax.xml.transform.TransformerConfigurationException error){
coderror=123;
msgerror=error.getMessage();
return null;
}
Source source = new DOMSource(doc);
StringWriter writer = new StringWriter();
Result result = new StreamResult(writer);
try{
transformer.transform(source,result);
}catch (javax.xml.transform.TransformerException error){
coderror=123;
msgerror=error.getMessage();
return null;
}
String s = writer.toString();
return s;
}
public Document string2DOM(String s)
{
Document tmpX=null;
DocumentBuilder builder = null;
try{
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
}catch(javax.xml.parsers.ParserConfigurationException error){
coderror=10;
msgerror="Error crando factory String2DOM "+error.getMessage();
return null;
}
try{
tmpX=builder.parse(new ByteArrayInputStream(s.getBytes()));
}catch(org.xml.sax.SAXException error){
coderror=10;
msgerror="Error parseo SAX String2DOM "+error.getMessage();
return null;
}catch(IOException error){
coderror=10;
msgerror="Error generando Bytes String2DOM "+error.getMessage();
return null;
}
return tmpX;
}