XML Catalog是OASIS制定的一种用于映射XML外部标识符到本地资源的规范,主要作用是让XML解析器在解析XML文件时,优先从本地路径加载DTD、XSD等外部资源,而不是去访问网络上的对应地址,既可以提升解析速度,也能避免网络不可用时的解析失败问题。

XML Catalog的核心概念
XML Catalog本质上是一个XML格式的配置文件,里面定义了外部资源的映射规则,常见的映射类型有两种:
- 公共标识符映射:针对XML文件中声明的公共ID进行映射,比如<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ...>中的公共ID部分。
- 系统标识符映射:针对XML文件中声明的系统路径(通常是URL)进行映射,比如上述声明中后面的DTD网络地址。
解析本地DTD文件的配置与实现
以Java环境为例,使用Xerces解析器配合XML Catalog解析本地DTD文件的步骤如下:
1. 准备本地DTD文件和Catalog配置
假设本地有一个自定义的DTD文件,路径为/opt/local_dtd/user.dtd,内容如下:
<!ELEMENT user (name, age)> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)>
编写Catalog配置文件catalog.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<!-- 映射系统标识符到本地DTD -->
<system systemId="http://ipipp.com/dtd/user.dtd" uri="/opt/local_dtd/user.dtd"/>
</catalog>
2. 编写解析代码
Java代码如下:
import org.apache.xerces.parsers.DOMParser;
import org.apache.xml.resolver.CatalogManager;
import org.apache.xml.resolver.tools.CatalogResolver;
import java.io.File;
public class DtdParseDemo {
public static void main(String[] args) throws Exception {
// 初始化Catalog管理器
CatalogManager catalogManager = new CatalogManager();
// 设置Catalog配置文件路径
catalogManager.setCatalogFiles("file:///opt/catalog.xml");
CatalogResolver resolver = new CatalogResolver(catalogManager);
// 创建解析器并设置解析器属性
DOMParser parser = new DOMParser();
parser.setFeature("http://xml.org/sax/features/validation", true);
// 设置实体解析器为CatalogResolver
parser.setEntityResolver(resolver);
// 解析包含DTD引用的XML文件
File xmlFile = new File("/opt/test_user.xml");
parser.parse(xmlFile.getAbsolutePath());
System.out.println("DTD解析完成,无错误");
}
}
待解析的XML文件test_user.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE user SYSTEM "http://ipipp.com/dtd/user.dtd">
<user>
<name>张三</name>
<age>25</age>
</user>
解析本地XSD文件的配置与实现
解析本地XSD文件的思路和解析DTD类似,只是映射的目标资源是XSD文件,同时解析器需要开启Schema验证功能。
1. 准备本地XSD文件和Catalog配置
本地XSD文件路径为/opt/local_xsd/user.xsd,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="user">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="age" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
更新Catalog配置文件,添加XSD的映射规则:
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="http://ipipp.com/dtd/user.dtd" uri="/opt/local_dtd/user.dtd"/>
<!-- 映射XSD系统标识符到本地文件 -->
<system systemId="http://ipipp.com/xsd/user.xsd" uri="/opt/local_xsd/user.xsd"/>
</catalog>
2. 编写XSD解析代码
Java代码如下:
import org.apache.xerces.parsers.DOMParser;
import org.apache.xml.resolver.CatalogManager;
import org.apache.xml.resolver.tools.CatalogResolver;
import java.io.File;
public class XsdParseDemo {
public static void main(String[] args) throws Exception {
CatalogManager catalogManager = new CatalogManager();
catalogManager.setCatalogFiles("file:///opt/catalog.xml");
CatalogResolver resolver = new CatalogResolver(catalogManager);
DOMParser parser = new DOMParser();
// 开启Schema验证
parser.setFeature("http://apache.org/xml/features/validation/schema", true);
parser.setEntityResolver(resolver);
File xmlFile = new File("/opt/test_user_xsd.xml");
parser.parse(xmlFile.getAbsolutePath());
System.out.println("XSD解析完成,无错误");
}
}
待解析的XML文件test_user_xsd.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<user xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ipipp.com/xsd/user.xsd">
<name>张三</name>
<age>25</age>
</user>
注意事项
- Catalog配置文件的路径需要是解析器可访问的绝对路径,或者配置为相对路径时确保解析器的工作目录正确。
- 如果同时有公共ID和系统ID的映射需求,优先配置系统ID映射,因为大部分XML文件的外部资源引用会同时包含系统ID。
- 不同编程语言的XML解析库对XML Catalog的支持方式略有差异,但核心都是加载Catalog配置文件并替换默认的实体解析器。
XML_CatalogDTDXSDXML解析修改时间:2026-07-07 20:51:33