首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于解析分隔文本消息的DFDL模式

用于解析分隔文本消息的DFDL模式
EN

Stack Overflow用户
提问于 2021-05-16 00:30:22
回答 1查看 183关注 0票数 0

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

XML/树输出应如下所示

代码语言:javascript
复制
<root>
<CLIENT_ID>DESKTOPCLIENT</CLIENT_ID>
<LOCALE>en-US</LOCALE>
<ENCODE/>
</root>
EN

回答 1

Stack Overflow用户

发布于 2021-05-17 20:59:49

这是一个可能的解决方案,在Daffodil中进行了测试:

代码语言:javascript
复制
<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;分隔,例如:

代码语言:javascript
复制
  <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>

这将产生一个类似如下所示的信息集:

代码语言:javascript
复制
<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元素更改为下面的值是有效的:

代码语言:javascript
复制
<xs:element name="value" type="xs:string" nillable="true"
  dfdl:nilKind="literalValue" dfdl:nilValue="%ES;"
  dfdl:useNilForDefault="no"/>

在这种情况下,infoset以如下形式结束:

代码语言:javascript
复制
<element>
  <name>ENCODE</name>
  <value xsi:nil="true"></value>
</element>

Edit2: nillable属性是必需的,否则IBM DFDL会将空字符串值视为不存在,而不是具有空值。不存在会导致错误。DFDL规范的较新版本添加了一个新属性emptyElementParsePolicy,该属性允许您控制是将空字符串视为不存在,还是仅将其视为空字符串。Daffodil将此属性作为扩展实现,但缺省情况下将行为视为空。IBM DFDL将其视为缺席行为。在将此属性设置为不存在时,Daffodil具有类似于IBM DFDL的行为。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67548961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档