如何解决用于解析分隔文本消息的 DFDL 架构
需要 dfdl 的小帮助。我需要将下面的消息解析为 XML/树结构之类的东西。元素不是固定的和动态的。有时会出现一些其他元素。
XML/Tree 输出预期如下
<root>
<CLIENT_ID>DESKTOPCLIENT</CLIENT_ID>
<LOCALE>en-US</LOCALE>
<ENCODE/>
</root>
解决方法
这样的事情是一个可能的解决方案,在水仙花中进行了测试:
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/">
<xs:include schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" />
<xs:annotation>
<xs:appinfo source="http://www.ogf.org/dfdl/">
<dfdl:format
ref="GeneralFormat"
lengthKind="delimited"
/>
</xs:appinfo>
</xs:annotation>
<xs:element name="root" dfdl:initiator="%ESC;" dfdl:terminator="%SUB;">
<xs:complexType>
<xs:sequence dfdl:separator="%CAN;" dfdl:separatorPosition="prefix" dfdl:sequenceKind="unordered">
<xs:element name="CLIENT_ID" type="xs:string" dfdl:initiator="CLIENT_ID%NAK;" />
<xs:element name="LOCALED" type="xs:string" dfdl:initiator="LOCALE%NAK;" />
<xs:element name="ENCODE" type="xs:string" dfdl:initiator="ENCODE%NAK;" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
请注意,这假定单个元素的名称是固定的,并且它们都存在,尽管顺序无关紧要。如果您知道固定名称,但它们可能存在也可能不存在,您可以将 minOccurs="0"
添加到无序序列中的元素。
但是,DFDL 不允许动态元素名称,因此如果您不知道名称,则需要稍微不同的架构。相反,您需要将数据描述为无限数量的名称/值对,其中名称和值由 %NAK; 分隔,例如:
<xs:element name="root" dfdl:initiator="%ESC;" dfdl:terminator="%SUB;">
<xs:complexType>
<xs:sequence dfdl:separator="%CAN;" dfdl:separatorPosition="prefix">
<xs:element name="element" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence dfdl:separator="%NAK;" dfdl:separatorPosition="infix">
<xs:element name="name" type="xs:string" />
<xs:element name="value" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
这会产生一个看起来像这样的信息集:
<root>
<element>
<name>CLIENT_ID</name>
<value>DESKTOPCLIENT</value>
</element>
<element>
<name>LOCALE</name>
<value>en-US</value>
</element>
<element>
<name>ENCODE</name>
<value></value>
</element>
</root>
如果您需要 XML 标记来匹配问题中的名称字段,则您需要转换信息集。 XSLT 可以轻松完成这种转换。
编辑:似乎存在 IBM DFDL 不喜欢上述解决方案的问题。我不知道为什么,但它适用于 Apache Daffodil。关于 value 是空字符串的一些事情会导致问题。经过反复试验,我发现 IBM DFDL(和 Apache Daffodil 也是如此)可以接受,如果您指定空值元素应视为 nil。因此,将 value 元素更改为此有效:
<xs:element name="value" type="xs:string" nillable="true"
dfdl:nilKind="literalValue" dfdl:nilValue="%ES;"
dfdl:useNilForDefault="no"/>
在这种情况下,信息集最终会是这样的:
<element>
<name>ENCODE</name>
<value xsi:nil="true"></value>
</element>
Edit2:nillable 属性是必需的,否则 IBM DFDL 会将空字符串值视为不存在而不是具有空值。缺席会导致错误。较新版本的 DFDL 规范添加了一个新属性 emptyElementParsePolicy
,它允许您控制是将空字符串视为不存在还是仅将其视为空字符串。 Daffodil 将此属性实现为扩展,但默认为将其视为空行为。 IBM DFDL 将视为缺席行为。将此属性设置为不存在时,Daffodil 具有与 IBM DFDL 类似的行为。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。