Apache Xerces 常用 CLI 命令与工具详解

整理 Xerces-J 2.12.2 常用命令行工具:Maven 构建与 java 直跑、官方二进制包自带 sax.Counter、dom.Writer 等示例工具用法,以及 jps、jstat、ps 诊断命令实测回显。

Apache XercesApache Xerces2026/10/12

Apache Xerces 常用 CLI 命令与工具详解

一、工具体系总览

围绕 Apache Xerces-J(实测版本 2.12.2)的命令行工具分三类:

类别组成适用场景
构建与运行Maven(mvn)、JDK(java/javac/jar)工程化解析、校验程序的编译与运行
官方示例工具Xerces-J-bin.2.12.2.tar.gz 内的 xercesSamples.jar(sax.Counter、dom.Counter、dom.Writer、sax.Writer、xs.QueryXS 等)快速统计、格式转换、性能对比
诊断命令jps、jstat、ps验证 JVM 参数、观察解析期 GC 行为

先说一个实测结论:Maven Central 上的 xercesImpl-2.12.2.jar 不包含任何示例工具。对 jar 内类清单执行过滤,Counter、DOMWriter、SAXWriter 均无匹配;它们位于官方二进制包的 xercesSamples.jar 中,需要单独下载二进制包(4.4 节)。

前置环境(双系统实测一致):OpenJDK 17、Maven、工程 /root/xerces-demo(含 xercesImpl 2.12.2 依赖与 com.example.xerces 各示例类)。运行时 classpath 已导出到 /tmp/cp.txt,生成方式见 4.2 节。全部命令以 root 执行(演示密码 q1w2e3r4)。

二、Maven 构建与运行命令

2.1 编译打包

cd /root/xerces-demo
mvn -q package

构建成功后查看产物与依赖落盘位置:

# ls target/*.jar
target/xerces-demo-1.0.0.jar
# ls /root/.m2/repository/xerces/xercesImpl/2.12.2/
_remote.repositories
xercesImpl-2.12.2.jar
xercesImpl-2.12.2.jar.sha1
xercesImpl-2.12.2.pom
xercesImpl-2.12.2.pom.sha1

2.2 导出运行时 classpath

mvn -q dependency:build-classpath -Dmdep.outputFile=/tmp/cp.txt
cat /tmp/cp.txt

实测回显(xercesImpl 自动带入 xml-apis 1.4.01):

/root/xerces-demo/target/classes:/root/.m2/repository/xerces/xercesImpl/2.12.2/xercesImpl-2.12.2.jar:/root/.m2/repository/xml-apis/xml-apis/1.4.01/xml-apis-1.4.01.jar

2.3 用 exec 插件直接运行示例类

mvn -q exec:java -Dexec.mainClass=com.example.xerces.DomDemo
mvn -q exec:java -Dexec.mainClass=com.example.xerces.ValidateDemo

exec:java 在 Maven 自身进程中运行,因此 MAVEN_OPTS 的堆参数对其生效(实测见 4.6 节)。需要传参时用 -Dexec.args:

mvn -q exec:java -Dexec.mainClass=com.example.xerces.BigXmlGen -Dexec.args='/root/xerces-demo/big-books.xml 400000'

实测回显:

生成完成: /root/xerces-demo/big-books.xml 条数=400000 大小=38.2 MB 耗时=505 ms

2.4 检查 jar 内容

jar tf /root/.m2/repository/xerces/xercesImpl/2.12.2/xercesImpl-2.12.2.jar | grep -cE '\.class$'

实测回显:962。查看 ServiceLoader 声明:

jar tf /root/.m2/repository/xerces/xercesImpl/2.12.2/xercesImpl-2.12.2.jar | grep META-INF/services

实测回显:

META-INF/services/javax.xml.datatype.DatatypeFactory
META-INF/services/javax.xml.parsers.DocumentBuilderFactory
META-INF/services/javax.xml.parsers.SAXParserFactory
META-INF/services/javax.xml.stream.XMLEventFactory
META-INF/services/javax.xml.validation.SchemaFactory
META-INF/services/org.w3c.dom.DOMImplementationSourceList
META-INF/services/org.xml.sax.driver

三、java 命令直跑示例

3.1 运行自定义解析/校验程序

# DOM 解析遍历
java -cp target/classes:$(cat /tmp/cp.txt) com.example.xerces.DomDemo

# SAX 事件流(ns 参数开启命名空间感知)
java -cp target/classes:$(cat /tmp/cp.txt) com.example.xerces.SaxDemo ns

# XSD 校验(合法/违规/格式错误三用例)
java -cp target/classes:$(cat /tmp/cp.txt) com.example.xerces.ValidateDemo

三条命令的实测回显与《快速入门与集成示例》一文完全一致,此处不重复。带堆参数与 UTF-8 locale 的完整形态:

export LC_ALL=C.UTF-8
java -Xms256m -Xmx512m -cp target/classes:$(cat /tmp/cp.txt) com.example.xerces.BigXmlDom /root/xerces-demo/big-books.xml 20

实测回显:

解析目标: /root/xerces-demo/big-books.xml 大小=38.2 MB
JVM maxMemory(-Xmx)=512 MB totalMemory=258 MB
解析完成: 根元素=books book 节点数=400000 重复次数=20 总耗时=20386 ms 解析后堆占用约=455 MB maxMemory=512 MB

3.2 验证 JAXP 实现切换

# 场景 1:classpath 不含 xercesImpl
java -cp target/classes com.example.xerces.JaxpSwitchDemo

# 场景 2:classpath 含 xercesImpl(ServiceLoader 自动接管)
java -cp target/classes:$(cat /tmp/cp.txt) com.example.xerces.JaxpSwitchDemo

# 场景 3:显式系统属性
java -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl \
     -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl \
     -cp target/classes com.example.xerces.JaxpSwitchDemo

实测回显依次为:

场景 1:实际 DocumentBuilderFactory 实现: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
场景 2:实际 DocumentBuilderFactory 实现: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
场景 3:javax.xml.parsers.DocumentBuilderFactory = org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
        实际 DocumentBuilderFactory 实现: org.apache.xerces.jaxp.DocumentBuilderFactoryImpl

3.3 探测特性与属性支持情况

java -cp target/classes:$(cat /tmp/cp.txt) com.example.xerces.FeatureProbe core

实测回显(截取):

XMLReader 实现类: org.apache.xerces.parsers.SAXParser
---- Feature 探测 ----
OK        http://xml.org/sax/features/namespaces = true
OK        http://apache.org/xml/features/validation/schema = false
OK        http://apache.org/xml/features/nonvalidating/load-external-dtd = true
FAIL      http://apache.org/xml/features/validation/honour-all-schemaLocations -> SAXNotRecognizedException: Feature '...' is not recognized.

注意:honour-all-schemaLocations 在此探针中未识别是因为 URI 写法带了 /validation/ 段,正确 URI 为 http://apache.org/xml/features/honour-all-schemaLocations(实测可读,默认 false)。

四、官方二进制包自带工具

4.1 下载与解压

cd /opt
wget https://archive.apache.org/dist/xerces/j/binaries/Xerces-J-bin.2.12.2.tar.gz
sha256sum Xerces-J-bin.2.12.2.tar.gz
tar xzf Xerces-J-bin.2.12.2.tar.gz

实测:包大小 5,648,672 字节,SHA-256 为 1ad48949b2c7f0df91668f058d6ec773871adb5527b0b5c73dc2160ab5d162e2;解压出 xerces-2_12_2/ 目录,内含 xercesImpl.jar、xml-apis.jar、serializer.jar、resolver.jar、xercesSamples.jar 及 data/、samples/ 目录。

4.2 sax.Counter:解析统计与性能测量

运行前缀(本文以 $XJ 代指该 classpath):

cd /opt/xerces-2_12_2
java -cp xercesSamples.jar:xercesImpl.jar:xml-apis.jar:serializer.jar:samples/xs sax.Counter data/personal.xml

实测回显:

data/personal.xml: 12 ms (37 elems, 18 attrs, 140 spaces, 128 chars)

帮助与选项:

java -cp xercesSamples.jar:xercesImpl.jar:xml-apis.jar:serializer.jar:samples/xs sax.Counter -h

实测 usage(截取):

usage: java sax.Counter (options) uri ...

options:
  -p name     Select parser by name.
  -x number   Select number of repetitions.
  -n  | -N    Turn on/off namespace processing.
  -np | -NP   Turn on/off namespace prefixes.
  -v  | -V    Turn on/off validation.
  -s  | -S    Turn on/off Schema validation support.
  -f  | -F    Turn on/off Schema full checking.
  -hs | -HS   Turn on/off honouring of all schema locations.
  -xi | -XI   Turn on/off XInclude processing.
  -m  | -M    Turn on/off memory usage report
  -t  | -T    Turn on/off "tagginess" report.

defaults:
  Parser:     org.apache.xerces.parsers.SAXParser
  Namespaces: on
  Prefixes:   off
  Validation: off
  Schema:     off

4.3 校验相关选项的实测行为

坑一:-v 只含 DTD 校验,XSD 校验必须加 -s。 对声明了 xsi:noNamespaceSchemaLocation='personal.xsd' 的文档只加 -v,实测报:

[Error] personal-schema.xml:2:11: Document is invalid: no grammar found.
[Error] personal-schema.xml:2:11: Document root element "personnel", must match DOCTYPE root "null".

正确用法:

java -cp xercesSamples.jar:xercesImpl.jar:xml-apis.jar:serializer.jar:samples/xs sax.Counter -v -s data/personal-schema.xml

实测回显:

data/personal-schema.xml: 122 ms (37 elems, 19 attrs, 0 spaces, 268 chars)

坑二:校验失败退出码仍为 0。 把根元素改为未声明的 personnelX 后实测:

[Error] broken-schema.xml:3:50: cvc-elt.1.a: Cannot find the declaration of element 'personnelX'.
[Fatal Error] broken-schema.xml:41:3: The element type "personnelX" must be terminated by the matching end-tag "</personnelX>".

随后 echo $? 仍为 0。脚本化校验不能依赖 Counter 退出码,需解析输出或自行实现校验主程序。

文件不存在时的报错原文(实测):

error: Parse error occurred - /tmp/broken.xml (No such file or directory)
java.io.FileNotFoundException: /tmp/broken.xml (No such file or directory)

4.4 其他示例工具

# DOM 遍历计数(-v 输出三段耗时:解析;遍历;额外)
java -cp xercesSamples.jar:xercesImpl.jar:xml-apis.jar:serializer.jar:samples/xs dom.Counter -v data/personal.xml

实测回显:

data/personal.xml: 22;7;0 ms (37 elems, 18 attrs, 140 spaces, 128 chars)
# SAX 重写 XML
java -cp xercesSamples.jar:xercesImpl.jar:xml-apis.jar:serializer.jar:samples/xs sax.Writer data/personal.xml

实测回显(截取):

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

  <person contr="false" id="Big.Boss">
    <name><family>Boss</family> <given>Big</given></name>
    <email>chief@foo.com</email>
# DOM 序列化输出
java -cp xercesSamples.jar:xercesImpl.jar:xml-apis.jar:serializer.jar:samples/xs dom.Writer data/personal.xml
# Schema 内置类型查询(无参时显示 usage)
java -cp xercesSamples.jar:xercesImpl.jar:xml-apis.jar:serializer.jar:samples/xs xs.QueryXS

实测回显:usage: java dom.QueryXS uri ...

五、JVM 诊断命令

5.1 jps:确认进程与 JVM 参数

先在后台启动一个解析进程:

cd /root/xerces-demo
nohup java -Xms256m -Xmx512m -cp "target/classes:$(cat /tmp/cp.txt)" com.example.xerces.BigXmlDom /root/xerces-demo/big-books.xml 20 > /tmp/big.log 2>&1 &
jps -lv

实测回显:

7857 com.example.xerces.BigXmlDom -Xms256m -Xmx512m
7910 jdk.jcmd/sun.tools.jps.Jps -Dapplication.home=/usr/lib/jvm/java-17-openjdk-amd64 -Xms8m -Djdk.module.main=jdk.jcmd

Maven 方式运行(exec:java 复用 Maven 进程)时,jps -v 实测显示 Launcher 进程带上了 MAVEN_OPTS:

7170 Launcher -Xms256m -Xmx512m -Dclassworlds.conf=/usr/share/maven/bin/m2.conf -Dmaven.home=/usr/share/maven -Dlibrary.jansi.path=/usr/share/maven/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/root/xerces-demo

5.2 ps:查看完整命令行

ps -ef | grep [j]ava

实测回显:

root      7857  7848 99 14:46 ?        00:00:06 java -Xms256m -Xmx512m -cp target/classes:/root/.m2/repository/xerces/xercesImpl/2.12.2/xercesImpl-2.12.2.jar:/root/.m2/repository/xml-apis/xml-apis/1.4.01/xml-apis-1.4.01.jar com.example.xerces.BigXmlDom /root/xerces-demo/big-books.xml 20

取进程号的稳妥方式是 pgrep -x java(pgrep -f 会误匹配 shell 包装进程,实测踩坑)。

5.3 jstat:观察解析期 GC 行为

jstat -gcutil 7857 1000 3

实测回显(38.2 MB XML 的 DOM 解析过程中):

  S0     S1     E      O      M     CCS    YGC     YGCT     FGC    FGCT     CGC    CGCT       GCT
  0.00 100.00  10.53  99.86  91.58  62.69     44     0.518     0     0.000    12     0.014     0.532
  0.00 100.00  21.05  99.89  91.05  61.42     70     0.779     1     0.012    18     0.020     0.811
  0.00   0.00  17.54  24.64  91.05  61.42    103     1.025     3     0.035    25     0.028     1.089

老年代(O 列)长期逼近 100%,与 DOM 全量驻留内存的特征吻合;1 秒内 YGC 从 44 涨到 103,说明解析期产生大量临时对象。

5.4 jcmd/jinfo 的可用性说明

jcmd 7857 VM.flags
jinfo -flag MaxHeapSize 7857

实测两者均报同一错误:

com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file /tmp/.java_pid7857: target process 7857 doesn't respond within 10500ms or HotSpot VM not loaded

(空闲 JVM 下同样复现。)在 attach 不可用的环境中,验证堆参数请用 jps -lv(基于 hsperfdata 文件)与 ps 命令。

六、常用问题

Q1:xercesImpl jar 里为什么找不到 Counter? 实测 jar tf xercesImpl-2.12.2.jar | grep -i counter 无输出。示例工具在官方二进制包的 xercesSamples.jar 中,按 4.1 节下载解压即可。

Q2:Counter 校验失败为什么脚本没感知? Counter 校验失败退出码仍为 0(实测)。脚本要么解析 [Error] 输出行,要么改用自研校验主程序以返回码表达结果。

Q3:exec:java 报 OutOfMemoryError 怎么调? exec:java 运行在 Maven 进程内,堆参数由 MAVEN_OPTS 控制。实测 -Xmx256m 解析 38.2 MB XML 报 An exception occurred while executing the Java class. Java heap space,改为 512 MB 后成功(堆峰值约 455 MB)。

Q4:mvn -version 看不到 MAVEN_OPTS,怎么确认它生效了? Maven 3.5.4/3.6.3 的 mvn -version 确实不打印该变量(实测)。用 jps -v 看 Maven 进程实际参数,实测能直接看到 -Xms256m -Xmx512m。

Q5:pgrep 找到的进程号连不上 jstat? pgrep -f 按完整命令行匹配,会把包含类名的 shell 进程一并命中,实测对非 JVM 进程执行 jstat 报 Could not map vmid to user Name。改用 pgrep -x java。

Q6:大文件解析想看进度怎么办? sax.Counter 的 -x number 支持重复解析取均值,配合 -m 输出内存用量报告;自研程序可在回调中周期性打印行号(SAXParseException 的 getLineNumber 或 Locator)。

七、参考链接