需要对DFDL的小帮助。我需要将下面的消息解析为类似于XML/树结构的内容。元素不是固定的和动态的。有时还会出现一些其他元素。

XML/树输出应如下所示
<root>
<CLIENT_ID>DESKTOPCLIENT</CLIENT_ID>
<LOCALE>en-US</LOCALE>
<ENCODE/>
</root>发布于 2021-05-17 20:59:49
这是一个可能的解决方案,在Daffodil中进行了测试:
<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不支持dynami元素名称,因此如果您不知道名称,则需要一个稍有不同的模式。相反,您需要将数据描述为无边界数量的名称/值对,其中名称和值由%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标记与问题中的name字段匹配,则需要转换信息集。XSLT可以毫不费力地完成这种转换。
编辑: IBM DFDL似乎不喜欢上面的解决方案。我不知道为什么,但它适用于Apache Daffodil。值是空字符串会导致问题。经过反复试验,我发现如果您指定将空值元素视为nil,IBM DFDL (以及Apache Daffodil )也可以使用它。因此,将value元素更改为下面的值是有效的:
<xs:element name="value" type="xs:string" nillable="true"
dfdl:nilKind="literalValue" dfdl:nilValue="%ES;"
dfdl:useNilForDefault="no"/>在这种情况下,infoset以如下形式结束:
<element>
<name>ENCODE</name>
<value xsi:nil="true"></value>
</element>Edit2: nillable属性是必需的,否则IBM DFDL会将空字符串值视为不存在,而不是具有空值。不存在会导致错误。DFDL规范的较新版本添加了一个新属性emptyElementParsePolicy,该属性允许您控制是将空字符串视为不存在,还是仅将其视为空字符串。Daffodil将此属性作为扩展实现,但缺省情况下将行为视为空。IBM DFDL将其视为缺席行为。在将此属性设置为不存在时,Daffodil具有类似于IBM DFDL的行为。
https://stackoverflow.com/questions/67548961
复制相似问题