Brett McLaughlin 回顾了一些 XML 基础知识,从文档结构到久存争议的属性/元素问题。重新学习如何优化 XML 并确保拥有最佳结构。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
到目前为止,我撰写了很多关于 XML 及相关内容的文章和书籍,当回头重新审视这些文字的时候,结果却令我很吃惊。虽然我是一位程序员,喜欢深入到比特和字节(上大学的时候非常喜欢汇编语言),喜欢那种绝对控制的感觉,但总的来看,我的文章、技巧和著作关于 XML 本身讨论得越来越少,关于操作 XML 的 API、包装这些 API 的 API 以及根本不触及 XML 的其他 API 讨论得越来越多。
因此结果就是一个共性的问题:是否还记得如何实际编写好的 XML 文档?还知道如何区分 XML 好坏的标准么?本文回顾了几篇 XML 101 技巧系列的文章,希望我们在拥有各种工具的同时不会遗忘那些基本的原理。
第一步:正确使用不同的 XML 成分
最突出的显著问题之一是 XML 作者(从宽泛的意义上讲)将各种各样的内容都填塞到元素中。属性、处理指令 — 变成了过去时。
元素
元素在 XML 中最容易使用,很大程度上是因为 XML 作者倾向于完全 依靠元素。当然,这是错误 的,而且有很严重的副作用。XML 中的元素最适合表示具有某种层次结构或者可能 具有某种层次结构的数据(当然也有例外,不过这里讨论的是最佳用法)。首先举一个反例,人名(不含姓和中间名等)永远不可能有层次结构,它就是一个单词,如此而已。但是如果选择使用 name
元素,可能 也不错:至少能分解成名和姓,可能还有中间名、头衔和其他成分。因此下面这样使用元素实际上是不正确的:
<firstName>Bob</firstName>
|
应该用:
<name firstName="Bob"
lastName="Zemeckis"
title="Mr." />
|
如果还不明白为何不在 name 元素中嵌套 firstName
、lastName
以及 title
元素,请仔细阅读 上一段。下一节介绍 属性 时还将进一步讨论。
一般而言,如果一个元素不可能在文档的同一个地方出现多次(比如可能有家庭和办公两个不同类型的 address
元素,图书可能存在两个 author
元素),则应尽量使用属性。并不是说每次使用元素时都必须 出现两次,仅仅是可以 出现两次。
元素最适合文本数据这种说法也不正确,很多例子中元素只有属性而没有文本内容(建议阅读讨论属性的 下一节)。最重要的是要记住 XML 不仅仅 有元素,还有其他结构。
属性
尽管看起来像是废话,但无论如何只能对单值数据使用 XML 属性。比方说,如果使用关于人的元素,那些关于这个人的单值信息就是潜在的属性。社会保障号码、ID,可能还有出生日期 — 都是合适的候选属性。
当然和其他规则相比,属性规则有更多的例外。实际上,我认为属性的应用和应该达到的程度相比少得多。开发人员往往喜欢元素比较清晰的外观:
<person>
<ssn>489098723</ssn>
</person>
|
但是这样做毫无意义 — 社会保障号码绝对是单值数据。更糟的是,这样把数字当成元素会影响性能。像这种情况下访问元素的子元素时,必须首先取得元素节点然后遍历所有的子元素节点。社会保障号码可能是第一个节点,但也可能是最后一个节点,不能确定。得到那个 节点的子元素后再访问其值,该例中包括一个文本节点。中间要经过多个步骤:
- 获得父节点(
person
元素)。
- 访问父节点的子节点。
- 迭代寻找需要的子节点(
ssn
元素)。
- 可能需要规范化这个新元素的文本节点以简化后续操作。
- 得到元素的子节点。
- 取得文本子节点的值。
使用属性的话就简单多了:
- 访问父节点(
person
元素)。
- 访问属性。
- 迭代寻找需要的属性(
ssn
)。
- 取得属性值。
这种方法避免了规范化(属性只能有单一的文本值),也不需要处理子元素。我发现访问元素的属性几乎总比访问特定的子元素快。因此性能上的优势很明显,特别是对于成千上万次迭代的情况。
我的观点是,尽管看起来不太好看,XML 应这样使用:
<person ssn="489098723"
firstName="Bobby"
lastName="McKenza"
>
<occupation>
<occupation-type status="part-time"
job="author" />
<occupation-type status="part-time"
job="programmer" />
</occupation>
<address type="home"
street="112 E. Harney Way"
city="New York"
state="NY"
zip="10012" />
<!-- etc... -->
</person>
|
对大多数人来说可能有点奇怪,因为基本上所有信息都用属性表示。但是我相信这种方法更好,访问 10,000 或更多次时能够可观地提高效率(访问次数多可以将细微的性能改进叠加起来)。
处理指令
通常不使用处理指令或者 PI。但是,令人苦恼的是现在很多 XML 处理 API 要求把特殊代码或指令放在注释中、或者使用特殊的名称空间以及各种专用元素,甚至使用包含指令的元素。如果 XML 需要为处理 API 或者工具提供信息,这些信息就是处理指令,XML 有专门的机制。
以前肯定遇到过,特别是在 XSL 中:
<?xml version="1.0"?>
<?xml-stylesheet href="classic.xsl" type="text/html"?>
<?xml-stylesheet href="alternate.xsl" type="text/xml" alternate="yes"?>
<article>
<!-- etc ... -->
</article>
|
这里 PI 告诉 XSLT 处理程序应用于 XML 文档的样式表在哪里。不用考虑那些忽略该机制的 API(尽管首先想到的就是 JAXB),应该充分利用该机制,无论如何要比下面这种方法强:
<?xml version="1.0"?>
<!-- xml-stylesheet url="classic.xsl" document-type="text/html" -->
<!-- xml-stylesheet url="alternate.xsl" document-type="text/xml" -->
<article>
<!-- etc ... -->
</article>
|
我经常看到这样的代码。注释是没有意义的,使用注释并将其中的信息作为指令处理的 API 是危险的。Javadoc 和文档生成 API 使用注释,但至少作为文档而不是具有实际意义的指令使用。显然,如果选择的 API 要求这种标记,您可能继续使用,但应该认识到这并非按照 XML 本来的方式使用 XML。我相信 XML 规范的作者在这个问题上说得很明确了。
结束语
也许我早应该讨论这些问题,但我并不是 XML 纯粹论者。事实上我认为 XML 的很多东西愚蠢无聊、本末倒置或者是完全错误的。但是我的确 认为,既然选择使用 XML,一些基本的概念对于正确使用是必须的,否则何必选择 XML 呢?如果多值数据或者长数据不用元素,如果根本不使用属性,如果滥用或者不用处理指令,某个时候就会发现最好离开 XML 去编写自己的私有语言或解析器来处理您的数据。否则就得忍受 XML 的枷锁 — 冗长、奇形怪状的文档、编码问题等等 — 而没有任何好处 — 专用的高速解析器。
因此不要为了正确地使用 XML 或者取悦语义主宰者而考虑这些建议。对于您的编程生涯来说这些都不是恰当的理由。如果将其看作更有效地利用 XML、提高软件性能的办法,就是合情合理的了。继续前进吧,打破那些规则 —— 但必须有充分的理由!
分享到:
相关推荐
- **概述**:概述XML的核心概念和技术栈。 - **起源**:探讨XML的历史背景和发展历程。 - **W3C**:介绍W3C组织在制定XML标准方面的作用。 ##### 2. XML语言 - **Unicode**:讲解Unicode编码系统及其在XML中的应用...
Java Architecture for XML Binding (JAXB) 是Java平台中用于处理XML和Java对象之间转换的一个标准API。它使得在Java应用程序中使用XML数据变得更加方便,无需手动编写大量的转换代码。本教程将详细介绍JAXB如何实现...
在"java源码:Java转换xml.rar"这个压缩包中,包含了XStream 1.3版本的源代码,这是一个强大的工具,便于理解其内部工作原理并进行自定义配置。 XStream库是由Joe Walnes创建的,它的主要优点是简单易用和灵活性。...
Java XML文件操作类:Dom4jHelper源代码文件下载,实现的功能:解析url xml文档,遍历解析文档,遍历解析元素,解析文件,获得根元素,修改xml某节点的值,输出文件路径及文件名 如果输出文件为null,则默认为原xml文件,...
本示例涉及的核心知识点是将Java中的List对象与XML文档进行相互转换。这里,我们使用的库是dom4j-1.6.1.jar,这是一个强大的Java XML处理库。 首先,让我们详细了解一下List和XML。List是Java集合框架的一部分,它...
`XML2POJO.exe`是这个工具的可执行文件,用户只需运行它并指定输入的XML文件和输出的Java源代码目录,即可完成转换。使用这样的工具能够提高开发效率,减少手动编码的错误,并使得代码更易于理解和维护。 在实际...
- JDBC-XML:Java标准库中的接口,支持XML数据类型的SQL操作。 9. **XML安全**: - XML签名:确保XML文档的完整性和来源的真实性。 - XML加密:保护XML数据的隐私,防止未经授权的访问。 通过深入学习和实践...
本书第三版的更新可能包含了最新的XML处理API和技术,如DOM4J、JDOM、StAX等,这些都是Java中处理XML的常用库。 1. **DOM解析**:DOM(Document Object Model)是W3C推荐的一种解析XML的标准方式,它将XML文档映射...
Java中的JAXB(Java Architecture for XML Binding)是一个用于在Java对象和XML文档之间进行映射的标准API。这个技术使得开发者可以方便地将XML数据转换为Java对象,反之亦然。在给定的压缩包文件中,可能包含了实现...
1. **Java**:Java是一种广泛使用的面向对象的编程语言,具有跨平台、安全性强和性能优良的特点。在这个项目中,Java被用来实现RSS阅读器的后端逻辑和可能的前端交互。 2. **源码**:源码是指程序员编写的应用程序的...
Java代码PDF解析成XML是一项技术任务,涉及到Java编程语言、PDF文档处理和XML数据格式转换。在这个场景中,我们主要关注如何使用Java库iTextPDF将PDF文档中的内容解析为XML结构。 首先,我们需要理解PDF(Portable ...
例如,使用DOM解析XML: ```java DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new ...
总之,XML与Java对象的映射是Java开发中的重要环节,涉及多种技术和工具。开发者可以根据项目需求选择合适的工具,如JAXB、DOM、SAX、XStream等,进行高效的XML处理。同时,理解XML Schema和自定义映射的原理也是...
在Java开发中,XML(可扩展标记语言)和XSD(XML Schema定义)是常见的数据交换格式和技术。XML用于结构化数据的存储和传输,而XSD则为XML文档提供了语义验证的规则。本教程将详细介绍如何在Java环境中生成XML和XSD...
这个项目展示了如何使用Java技术栈构建一个功能完善的日程提醒系统,同时利用XML来存储和读取用户设定的提醒信息。 【描述】在这款系统中,Java作为后端开发语言,提供了强大的数据处理和逻辑控制能力。XML...
在这个压缩包中,你将找到Xerces的源代码,这对于学习和理解XML解析机制以及深入研究Java XML处理技术非常有帮助。 XML(eXtensible Markup Language)是一种用于标记数据的语言,广泛用于存储和传输结构化数据。...
标准Dom、JDom(为Java提供的解析技术)、Dom4j(优化之后的解析技术)、SAX(大型xml解析的技术) 树模型:DOM、JDOM、Dom4j; 特点:算法丰富、操作比较简单;一次性读取所有内容到内存(不适于大型xml文件解析...
使用java jdk的JAXB技术实现xml与java对象互相转化代码教程: JDK中JAXB相关的重要Class和Interface:(来源于百度百科JAXB) •JAXBContext类,是应用的入口,用于管理XML/Java绑定信息。 •Marshaller接口,将Java...
这个项目涉及了数据处理和文件操作的核心技能,对理解数据库操作、Java编程以及XML数据序列化有很高的实践价值。掌握这些技术对于开发需要数据交换和持久化的应用程序至关重要。此外,了解如何在Java中有效地使用...
Java提供了多种库来解析和操作XML文档,其中JDOM(Java Document Object Model)是一个广泛使用的开源库,它提供了简单且强大的API来读取、创建和修改XML文档。 ### Java解析XML字符串 在给定的代码示例中,我们...