Apache Daffodil 配置参数详解
Apache Daffodil 4.2.0 配置参数详解,梳理 DFDL schema 关键格式属性(编码、长度、字节序、数值与定界)与运行时 tunable 参数、-T/-D/--config 覆盖方式及 JVM 调优。
Apache Daffodil 配置参数详解
本文汇总 Apache Daffodil 4.2.0 的两类配置:一是决定「数据长什么样」的 DFDL schema 格式属性,二是决定「Daffodil 运行时行为」的 tunable 参数与 JVM 参数。所有参数名与默认值均来自发行版自带 schema(
org/apache/daffodil/xsd/DFDLGeneralFormatBase.dfdl.xsd、dafext.xsd)实测。
一、配置体系概览
Daffodil 的配置分为三层:
| 层级 | 载体 | 作用 | 生效方式 |
|---|---|---|---|
| DFDL schema 属性 | dfdl: 命名空间属性 | 描述字段编码、长度、字节序、数值格式等 | 写入 .dfdl.xsd,parse/unparse 时自动读取 |
| Tunables | 运行时开关 | 调整 Daffodil 解析/回写行为与限制 | CLI -T / --config XML / API withTunable |
| JVM 参数 | DAFFODIL_JAVA_OPTS | 堆大小、代码缓存等 | 环境变量 |
DFDL schema 中常通过 <dfdl:format> 集中声明一组默认属性,再在各元素上用属性覆盖。官方通用默认集由 DFDLGeneralFormat.dfdl.xsd 提供,schema 需显式 include:
<xs:include schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
<dfdl:format ref="tns:GeneralFormat" encoding="ASCII" representation="text"/>
</xs:appinfo>
</xs:annotation>
二、DFDL schema 关键格式属性
2.1 编码与表示
| 属性 | 取值 | 含义 |
|---|---|---|
dfdl:encoding | 如 ASCII、US-ASCII、UTF-8、UTF-16 | 文本字符编码,官方默认 US-ASCII |
dfdl:representation | text / binary | 字段是文本还是二进制 |
dfdl:encodingErrorPolicy | error / replace | 解码遇到非法字节时的策略,官方默认 replace |
dfdl:utf16Width | fixed / variable | UTF-16 宽度,官方默认 fixed |
示例(定长文本):
<dfdl:format ref="tns:GeneralFormat" encoding="ASCII" representation="text"/>
2.2 长度相关
| 属性 | 取值 | 含义 |
|---|---|---|
dfdl:lengthKind | implicit / explicit / delimited / prefixed / pattern / endOfParent | 长度确定方式;官方默认 implicit |
dfdl:length | 非负整数或表达式 | lengthKind="explicit" 时的固定长度 |
dfdl:lengthUnits | characters / bytes / bits | 长度单位,官方默认 bytes |
dfdl:truncateSpecifiedLengthString | yes / no | 超长字符串是否截断,默认 no |
dfdl:leadingSkip / dfdl:trailingSkip | 整数 | 字段前后跳过的单位数,默认 0 |
示例:定长 5 字符
<xs:element name="name" type="xs:string"
dfdl:lengthKind="explicit" dfdl:length="5" dfdl:lengthUnits="characters"/>
2.3 对齐与字节序
| 属性 | 取值 | 含义 |
|---|---|---|
dfdl:alignment | 整数(默认 1) | 对齐边界 |
dfdl:alignmentUnits | bits / bytes(仅此两种) | 对齐单位,官方默认 bytes;不支持 characters |
dfdl:byteOrder | bigEndian / littleEndian | 二进制多字节整数字节序,官方默认 bigEndian |
dfdl:bitOrder | mostSignificantBitFirst / leastSignificantBitFirst | 位序,官方默认 mostSignificantBitFirst |
注意:
alignmentUnits的合法枚举只有bits/bytes,写成characters会报cvc-enumeration-valid错误。
2.4 文本数值格式
| 属性 | 取值 | 含义 |
|---|---|---|
dfdl:textNumberRep | standard / zoned / packed | 文本数值表示,官方默认 standard |
dfdl:textNumberPattern | 如 000、#,##0.### | 数值格式模式,官方默认 #,##0.###;-#,##0.### |
dfdl:textNumberCheckPolicy | strict / lax | 数值校验严格程度,官方默认 lax |
dfdl:textNumberJustification | left / right / center | 对齐方式,官方默认 right |
dfdl:textNumberPadCharacter | 如 %SP; | 填充字符,官方默认空格 |
dfdl:textStandardBase | 2 … 36 | 进制,官方默认 10 |
dfdl:textStandardDecimalSeparator | 默认 . | 小数点 |
dfdl:textStandardGroupingSeparator | 默认 , | 千分位 |
dfdl:textStandardZeroRep | 字符串 | 零的特殊表示,默认空 |
dfdl:decimalSigned | yes / no | 是否带符号,默认 yes |
示例:让 3 位年龄字段在回写时零填充为 025——
<xs:element name="age" type="xs:unsignedInt"
dfdl:lengthKind="explicit" dfdl:length="3" dfdl:lengthUnits="characters"
dfdl:textNumberPattern="000"/>
parse 后 age=25,unparse 后原样还原 025(字节级一致)。
2.5 定界符与内容标记
| 属性 | 含义 | 官方默认 |
|---|---|---|
dfdl:initiator | 字段起始标记 | 空 |
dfdl:terminator | 字段结束标记 | 空 |
dfdl:separator | 兄弟元素分隔符 | 空 |
dfdl:separatorPosition | infix / prefix / postfix | infix |
dfdl:separatorSuppressionPolicy | anyEmpty 等 | anyEmpty |
dfdl:emptyValueDelimiterPolicy | both / none 等 | both |
dfdl:outputNewLine | 如 %LF;、%CR;%LF; | %LF; |
2.6 结构与出现次数
| 属性 | 取值 | 含义 |
|---|---|---|
dfdl:sequenceKind | ordered / unordered | 序列是否有序,默认 ordered |
dfdl:occursCountKind | implicit / parsed / fixed / expression / stopValue | 数组计数方式,默认 implicit |
dfdl:initiatedContent | yes / no | 内容是否由 initiator 引导,默认 no |
dfdl:choiceLengthKind | implicit / explicit | 选择分支长度方式,默认 implicit |
dfdl:ignoreCase | yes / no | 标记匹配是否忽略大小写,默认 no |
2.7 空值与缺省处理
| 属性 | 取值 | 含义 |
|---|---|---|
dfdl:nilValue | 字符串或 % 实体 | nil(空值)字面量 |
dfdl:nilKind | literalValue / logicalValue / logicalNil | nil 判定方式 |
dfdl:useNilForDefault | yes / no | 缺省值是否用 nil 表示 |
dfdl:emptyElementParsePolicy | treatAsEmpty / treatAsAbsent / treatAsError | 空元素处理策略 |
三、Daffodil 运行时 Tunable 参数
Tunable 控制 Daffodil 运行时的行为与安全限制,默认值来自 dafext.xsd。常用项如下:
| Tunable | 默认值 | 含义 |
|---|---|---|
maxOccursBounds | 2147483647 | 数组最大出现次数上限,防止超大数组耗尽内存 |
maxSkipLengthInBytes | 1024 | 单个 skip 区段最大字节数 |
maxFieldContentLengthInBytes | 1048576 | 字段内容最大字节数 |
maxHexBinaryLengthInBytes | 1073741823 | hexBinary 最大字节数 |
maxLookaheadFunctionBits | 512 | lookahead 函数最大位宽 |
maxBinaryDecimalVirtualPoint | 200 | 二进制十进制虚拟点上限 |
minBinaryDecimalVirtualPoint | -200 | 二进制十进制虚拟点下限 |
blobChunkSizeInBytes | 4096 | 大对象读写分块大小 |
outputStreamChunkSizeInBytes | 65536 | 输出流分块大小 |
readerByteBufferSize | 8192 | 读取缓冲字节数 |
inputFileMemoryMapLowThreshold | 33554432 | 低于该大小用内存映射读取输入文件 |
initialElementOccurrencesHint | 10 | 数组初始容量提示(性能) |
infosetWalkerMode | streaming | 信息集遍历模式 |
infosetWalkerSkipMin | 32 | 信息集遍历跳过下限 |
infosetWalkerSkipMax | 2048 | 信息集遍历跳过上限 |
infosetIncludeDataType | false | 信息集是否附带数据类型 |
unqualifiedPathStepPolicy | noNamespace | 非限定路径步的命名空间解析策略 |
parseUnparsePolicy | fromRoot | 解析/回写是否从根元素开始 |
invalidRestrictionPolicy | error | 无效 XSD restriction 的处理策略 |
defaultEmptyElementParsePolicy | treatAsEmpty | 默认空元素策略 |
escalateWarningsToErrors | false | 是否把警告升级为错误 |
errorOnUnsupportedJavaVersion | true | 不支持的 JDK 版本是否报错 |
allowExternalPathExpressions | false | 是否允许外部路径表达式(调试用,影响性能) |
allowExpressionResultCoercion | true | 表达式结果类型不匹配时是否隐式转换 |
generatedNamespacePrefixStem | tns | 生成信息集时的命名空间前缀词干 |
maxDataDumpSizeInBytes | 256 | 数据转储最大字节数 |
releaseUnneededInfoset | true | 是否及时释放不再需要的信息集 |
saxUnparseEventBatchSize | 100 | SAX 回写事件批大小 |
unparseSuspensionWaitOld | 100 | 回写挂起等待(旧) |
unparseSuspensionWaitYoung | 5 | 回写挂起等待(新) |
此外还有若干 requireXxxProperty(如 requireTextStandardBaseProperty、requireEncodingErrorPolicyProperty)与 suppressSchemaDefinitionWarnings,用于控制 schema 校验的严格程度,默认均为宽松(false / 不抑制)。
四、在命令行覆盖配置
4.1 单次 tunable(-T)
daffodil parse -s person.dfdl.xsd -TmaxOccursBounds=1000 person.txt
真实回显(exit=0,即正常解析输出):
<?xml version="1.0" encoding="UTF-8"?>
<tns:person xmlns:tns="http://example.com/dfdl/person">
<name>Alice</name>
<age>25</age>
<code>AB</code>
</tns:person>
可一次指定多个 tunable:
daffodil parse -s person.dfdl.xsd -TmaxOccursBounds=1000 -TmaxSkipLengthInBytes=2048 person.txt
Tunable 名必须与版本匹配,写错会抛出
IllegalArgumentException(提示 Unknown tunable 及写错的 Tunable 名称)。
4.2 外部变量(-D)
对 schema 中声明的 dfdl:defineVariable,用 -D 传值:
daffodil parse -s person.dfdl.xsd -DsomeVar=value person.txt
若变量未在 schema 中定义,会报 [error] Variable definition not found: someVar。
4.3 配置文件(--config / -c)
--config 接收一个 XML 文件,可同时配置 tunables 与外部变量绑定。示例 daffodil-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<daf:configuration xmlns:daf="urn:ogf:dfdl:2013:imp:daffodil.apache.org:2018:ext">
<daf:tunables>
<daf:maxOccursBounds>1000</daf:maxOccursBounds>
<daf:maxSkipLengthInBytes>2048</daf:maxSkipLengthInBytes>
</daf:tunables>
</daf:configuration>
使用:
daffodil parse -s person.dfdl.xsd -c daffodil-config.xml person.txt
daffodil save-parser -s person.dfdl.xsd -c daffodil-config.xml person.parser.bin
两者均 exit=0,说明配置被正确加载。
五、JVM 参数调优
Daffodil 启动脚本(bin/daffodil)默认注入 -Xms1024m -Xmx1024m -XX:ReservedCodeCacheSize=128m。可通过 DAFFODIL_JAVA_OPTS(优先级高于 JAVA_OPTS)覆盖,重启进程生效:
export DAFFODIL_JAVA_OPTS="-Xms256m -Xmx512m"
daffodil --version
真实回显:
Apache Daffodil 4.2.0
覆盖时务必同时下调
-Xms:若只写-Xmx512m而默认-Xms1024m仍生效,会因「初始堆大于最大堆」启动失败。
Error occurred during initialization of VM
Initial heap size set to a larger value than the maximum heap size
六、典型调优场景
| 场景 | 建议 |
|---|---|
| 解析大数组导致内存偏高 | 下调 maxOccursBounds;用 DAFFODIL_JAVA_OPTS="-Xms256m -Xmx512m" 限制堆 |
报 Schema Definition Warning(提示某属性 is required but not defined) | 在 dfdl:format 中显式补全该属性,或用 tunable suppressSchemaDefinitionWarnings 抑制 |
| 严格校验 schema 完整性 | 开启相应 requireXxxProperty(如 requireTextStandardBaseProperty=true) |
| 严格模式:把警告当错误 | escalateWarningsToErrors=true |
| 生产环境性能 | 关闭 allowExternalPathExpressions;复用 save-parser 产物避免重复编译 schema |
| 调试时查看表达式 | 临时开启 allowExternalPathExpressions=true(会降低性能,勿用于生产) |