java XML 简单使用

概述

什么是 XML?

XML 是一种非常有用的描述结构化信息的技术。

基本使用

例如把一个属性(property file)文件更改为 XML 文件:

Property 属性文件:

city=hangzhou
school=zjut
name=huangguosheng
age=19

XML 文件:

<config>
    <city>hangzhou</city>
    <school>zjut</school>
    <name>huangguosheng</name>
    <age>19</age>
</config>

XML 文档的结构

基本结构

  • 文档头
  • 文档定义类型
  • 根元素

文档头

XML 文档应当以一个文档头开始,例如:

<?xml version="1.0"?>

或者

<?xml version="1.0" encoding="UTF-8"?>

严格来说,文档头是可选的,但是强烈推荐使用文档头。(摘自《Java 核心技术 卷2》)

文档定义类型

文档头之后通常是文档类型定义(Document Type Definition,DTD),例如:

<!DOCTYPE beans SYSTEM "application.dtd">

关于文档定义类型的规则,会在后文阐述。

根元素

最后是 XML 的根元素,根元素包含其它元素。

例如一个完整的 XML 文档:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans SYSTEM "application.dtd">
<beans>
    <bean id="Message" class="com.zhuye.test.impl.MessageImpl"/>
</beans>

XML 元素

子元素

元素可以有子元素、文本或两者都有。但在设计 XML 文档时,为了简化解析过程,最好让元素要么包含子元素,要么包含文本。

子元素例:

<beans>
    <bean>
        <property>666</property>
    </bean>
    <bean>
        <property>999</property>
    </bean>
</beans>

属性

XML 元素可以包含属性。例如:

<beans>
    <bean id="Message" class="com.zhuye.test.impl.MessageImpl"/>
</beans>

其中的 idclass 都是属性。而 Messagecom.zhuye.test.impl.MessageImpl 均为属性值。

对于属性的使用,有一条经验法则:属性只用来修改值的解释,而不用来指定值。

其它标记

了解

字符引用

  • &# :十进制;

  • &#x :十六进制;

实体引用

  • &lt :小于
  • &gt :大于
  • &amp :&
  • &quot :引号
  • apos :省略号

CDATA 部分

<![CADTA[ 开头,以 ]]> 结尾。

处理指令

<??>

<?xml version="1.0"?>

注释

<-- this is a comment -->

解析 XML 文档

获取文档构建器

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();

从文件中读入文档

有三种方法:

第一种:解析文件对象。

File f = ...;
Document doc = builder.parse(f);

第二种:解析 URL

URL u = ...;
Document doc = builder.parse(u);

第三种:通过输入流解析。

InputStream in = ...;
Document doc = builder.parse(in);

获取根元素

Element root = doc.getDocumentElement();

获取元素的子元素

NodeList children = root.getChildNodes();

获取元素的值

String text = children.item(0).getData().trim();

获取元素属性

获取全部属性

String attr = beans.item(0).getAttributes().toString();

获取某个属性

String className = beans.item(0).getAttributes().getNamedItem("class");

获取某个属性的属性值

String className = beans.item(0).getAttributes().getNamedItem("class").getNodeValue();

方法总览

javax.xml.parsers.DocumentBuilderFactory

  • static DocumentBuilderFactory newInstance() :返回 DocumentBuilderFactory 的一个实例。
  • DocumentBuilder newDocumentBuilder() :返回 DocumentBuilder 类的一个实例。

javax.xml.parsers.DocumentBuilder

  • Document parse(File f) :解析来自给定文件,返回解析后的文档。
  • Document parse(String url) :解析来自给URL,返回解析后的文档。
  • Document parse(InputStream in) :解析来自给定输入流,返回解析后的文档。

org.w3c.dom.Document

  • Element getDocumentElement() :返回文档的根元素。

org.w3c.dom.Element

  • String getTagName() :返回元素的名字。
  • String getAttributes(String name) :返回给定名字的属性值,没有该属性值时返回空字符串。

org.w3c.dom.Node

  • NodeList getChildNodes() :返回包含该节点所有子元素的节点列表。
  • Node getFirstChild() :获取该节点的第一个子节点。在该节点没有节点时返回 null
  • Node getLastChild() :获取该节点的最后一个子节点。在该节点没有节点时返回 null
  • Node getNextSibling() :获取该节点的下一个节点,当没有时,返回 null
  • Node getPreviousSibling() :获取该节点的上一个节点,当没有时,返回 null
  • Node getParentNode() :获取该节点的父节点,当没有时,返回 null
  • NamedNodeMap getAttributes() :返回含有描述该节点所有属性的 Attr 节点的映射表。
  • String getNodeName() :返回该节点的的名字。当该节点为 Attr 节点时,该名字就是属性名。
  • String getNodeValue() :赶回该节点的值。当该节点为 Attr 节点时,该值就是属性值。

org.w3c.dom.CharacterData

  • String getData() :返回存储在节点中的文本。

org.w3c.dom.NodeList

  • int getLength() :返回列表中的节点数。
  • Node item(int index) :返回给定索引值处的节点。

org.w3c.dom.NamedNodeMap

  • int getLength() :返回该节点映射表中的节点数。
  • Node item(int index) :返回给定索引值处的节点。

验证 XML 文档

对以下 XML 元素:

<font>
    <name>Helvetica</name>
    <size>36</size>
</font>

我们可以规定以下验证:(前提是 namesize 都已经被声明)

<!ELEMENT font (name,size)>

以上为文档类型定义(DTD)的验证。

还有一种 XML Schema 定义:

<xsd:element name="font">
	<xsd:sequence>
    	<xsd:element name="name" type="xsd:string"/>
        <xsd:element name="size" type="xsd:int"/>
    </xsd:sequence>
</xsd:element>

DTD 相比,XML Schema 可以表达更加复杂的验证条件。

这里只介绍文档类型定义(DTD)

文档类型定义

提供 DTD 的方式有以下几种:

1、直接写入 xml 文档:

<?xml version="1.0"?>
<!DOCTYPE config[
	<!ELEMENT config...>
	...
]>
<config>
	...
</config>

此方法应用并不普遍。

2、把 DTD 存储在外部,此时,需要给 xml 指定一个包含 DTDURL

<!DOCTYPE config SYSTEM "config.dtd">

或者:

<!DOCTYPE config SYSTEM "http://myserver.com/config.dtd">

3、使用网络上的 DTD 文件:

<!DOCTYPE hibernate-configuration PUBLIC
         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

元素内容规则

规则 含义
E* 0个或多个E
E+ 1个或多个E
E? 0个或1个E
E1|E2|...|En E1,E2,...En中的一个
E1,E2,...En E1后面跟着E2,...,En
#PCDATA 文本
(#PCDATA|E1|E2|...|En)* 0或多个文本且E1,E2,...,En以任意顺序排列(混合式内容)
ANY 允许有任意子元素
EMPTY 不允许有子元素

示例:

<!ELEMENT beans (bean)*>
<!ELEMENT bean (property*)>
<!ELEMENT property EMPTY>

元素属性

通用语法:

<!ATTLIST element attribute type default>

属性类型:

类型 含义
CDATA 任意字符串
(A1|A2|...|An) 字符串属性A1,A2,...An之一
NMTOKEN,NMTOKENS 一个或多个名字标记
ID 一个唯一的ID
IDREF,IDREFS 一个或多个对唯一ID的引用
ENTITY,ENTITIES 一个或多个为解析的实体

默认值

默认值 含义
#REQUIRED 属性是必须的
#IMPLIED 属性是可选的
A 属性的可选的;若未指定、解析器报告的属性是A
#FIXED A 属性必须是未指定的或者是A;在这两种情况下,解析器报告的属性都是A

示例:

<!ELEMENT beans (bean)*>
<!ELEMENT bean (property*)>
<!ELEMENT property EMPTY>

<!ATTLIST bean id ID #REQUIRED>
<!ATTLIST bean class CDATA #REQUIRED>

<!ATTLIST property name CDATA #REQUIRED>
<!ATTLIST property value CDATA #IMPLIED>
<!ATTLIST property ref CDATA #IMPLIED>

关于 XML Schema 参考:Schema 教程 (w3school.com.cn)

一个典型的示例

dtd 文件

<?xml version="1.0" encoding="UTF-8" ?>

<!ELEMENT beans (bean)*>
<!ELEMENT bean (property*)>
<!ELEMENT property EMPTY>

<!ATTLIST bean id ID #REQUIRED>
<!ATTLIST bean class CDATA #REQUIRED>

<!ATTLIST property name CDATA #REQUIRED>
<!ATTLIST property value CDATA #IMPLIED>
<!ATTLIST property ref CDATA #IMPLIED>

xml 文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans SYSTEM "application.dtd">
<beans>
    <bean id="Message" class="com.zhuye.test.impl.MessageImpl"/>
</beans>

java 解析

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();

URL u = IocApplication.class.getResource("/application.xml");
Document doc = builder.parse(String.valueOf(u));

Element root = doc.getDocumentElement();
NodeList beans = root.getElementsByTagName("bean");
posted @   临安剑客  阅读(86)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示