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、提高软件性能的办法,就是合情合理的了。继续前进吧,打破那些规则 —— 但必须有充分的理由!
分享到:
相关推荐
在"java源码:Java转换xml.rar"这个压缩包中,包含了XStream 1.3版本的源代码,这是一个强大的工具,便于理解其内部工作原理并进行自定义配置。 XStream库是由Joe Walnes创建的,它的主要优点是简单易用和灵活性。...
本示例涉及的核心知识点是将Java中的List对象与XML文档进行相互转换。这里,我们使用的库是dom4j-1.6.1.jar,这是一个强大的Java XML处理库。 首先,让我们详细了解一下List和XML。List是Java集合框架的一部分,它...
而Java作为一种主流的编程语言,在处理XML方面有着丰富的工具和技术支持。Java绑定XML架构,即通过Java代码与XML文档之间的映射来简化XML操作的过程,是实现异构系统间数据共享的关键技术之一。 #### 二、Java绑定...
在Java编程中,XML(eXtensible Markup Language)是一种常用的数据交换格式,它具有结构化、可扩展性,常用于存储和传输数据。本文将详细介绍如何使用Java来读取和修改XML文件,主要涉及以下几个核心知识点: 1. *...
Java提供了多种解析器,如DOM(Document Object Model)、SAX(Simple API for XML)和StAX(Streaming API for XML)。DOM解析器将整个XML文档加载到内存中的树形结构,方便遍历和修改;SAX是事件驱动的解析器,...
本书第三版的更新可能包含了最新的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. **源码**:源码是指程序员编写的应用程序的...
本资源包含的是XML与Java相关的源代码,适合初学者和有经验的开发者学习和参考。 在Java中,处理XML主要有以下几种方式: 1. DOM(Document Object Model):这是一种将整个XML文档加载到内存中的方法,形成一个树...
例如,使用DOM解析XML: ```java DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new ...
2. **读取XML到Java对象**: 创建一个`XmlMapper`对象,然后调用`bindMapToReader()`或`bindMapToInputStream()`方法,传入XML文件的输入源和之前配置的映射。这会将XML数据解析成Java对象。 3. **Java对象到XML**: ...
《Java, XML和Web服务宝典》是一本深入探讨Java技术、XML以及Web服务的综合性技术书籍。这三者在现代软件开发中扮演着至关重要的角色,尤其在构建分布式系统和互联网应用程序时。以下是这些主题的主要知识点: 1. *...
将XML数据转换为Java对象,能够方便地在两者之间进行数据操作和处理。在这个过程中,XStream库扮演了关键角色。 XStream是一个强大的Java库,它可以将Java对象序列化为XML,同时也能将XML反序列化为等效的Java对象...
为了简化从XML到Java对象的映射过程,Java社区开发了各种工具和库,其中“XML2Java”是一个专门用于将XML文件转换为Java源代码类的库。这个库为开发者提供了便捷的方式,将XML结构转换为对应的Java类,从而减少手动...
本部分我们将深入探讨Java与XML的结合使用,以及如何通过Java技术进行XML编程。 1. **Java中的XML解析器**: Java提供了多种XML解析器,如DOM(Document Object Model)、SAX(Simple API for XML)和StAX...
Java代码PDF解析成XML是一项技术任务,涉及到Java编程语言、PDF文档处理和XML数据格式转换。在这个场景中,我们主要关注如何使用Java库iTextPDF将PDF文档中的内容解析为XML结构。 首先,我们需要理解PDF(Portable ...
《Java,XML和Web服务宝典》是一本深入探讨Java技术、XML以及Web服务的综合性技术书籍。在当今数字化世界中,这三者是构建分布式系统、实现数据交换和提供网络服务的关键技术。 首先,Java作为全球最广泛使用的编程...
《Java与XML第三版》是一本深入探讨Java与XML集成技术的专业书籍,旨在帮助开发者理解和应用这两种技术在软件开发中的协同工作。XML(Extensible Markup Language)作为一种数据交换和存储的标准,广泛应用于分布式...
在Java开发中,XML(可扩展标记语言)和XSD(XML Schema定义)是常见的数据交换格式和技术。XML用于结构化数据的存储和传输,而XSD则为XML文档提供了语义验证的规则。本教程将详细介绍如何在Java环境中生成XML和XSD...
Java XML编程指南主要涵盖的是如何在Java环境中处理XML(可扩展标记语言)文档的技术和方法。XML作为一种数据交换和存储格式,广泛应用于不同系统之间的数据交互,如Web服务、配置文件、数据序列化等。本指南将深入...