I think you are going to have to write a special XML comparison tool.

The unordered issue is usually handled by cannonicalization - i.e., sort things 
first, then verify the result of the sort against your expected data.


You can use the XML comparison tool we wrote for the Daffodil TDML runner as a 
starting point for yours if you want.


Look in XMLUtils.scala in daffodil-lib.


The usual trick with such comparison tools is getting out useful diagnostic 
info for when items are NOT equal, and not stopping at the first little 
inequality, but somehow "resynchronizing" back to the subsequent parts of the 
data that are still the same, so you can continue comparing more of the 
structure. This is not always possible (nor required for your use case perhaps) 
but is one of the bigger challenges.


I really recommend this approach of building a test rig like your own 
specialized TDML that exactly lets you express the tests you want, does the 
kind of comparison you want, etc.  This was one of the really good decisions we 
made early on in Daffodil development and has paid off very well.


These kinds of comparison tools are very easy to write in Scala using its XML 
support. Some people in the scala community are suggesting switching to 
different XML libraries, but I have not found a need for that, and Daffodil 
makes very heavy use of the original scala.xml library.







________________________________
From: Christofer Dutz <christofer.d...@c-ware.de>
Sent: Tuesday, January 29, 2019 7:29:43 AM
To: users@daffodil.apache.org
Subject: [TDML] Options to ignore values and ordering?


Hi all,



I am currently trying to use DFDL, to define the interaction in industrial 
protocols with DFDL and SCXML (Other thread).

Now I am defining in my SCXML document message content being sent via DFDL. 
However when defining the receiving part I would need something I could imagine 
is part of TDML.



In my case a response can contain a number of parameters. Each parameter having 
different payload. However the order of these is not pre-defined. I would like 
to do something like this:



<state id="receiveCotpConnectionResponse">
  <onentry>
    <plc4x:receive timeout="5000">
      <s7:tpktMessage>
        <magicByte>3</magicByte>
        <reserved>0</reserved>
        <!-- Just ignore the content of this field, we don't care about it as 
it's only required for parsing. -->
        <length><plc4x:ignore/></length>
        <userData>
          <!-- Just ignore the content of this field, we don't care about it as 
it's only required for parsing. -->
          <headerLength><plc4x:ignore/></headerLength>
          <type>208</type>
          <CotpTpduConnectionResponse>
            <!-- Make sure the reply uses the same reference as we used in the 
request. -->
            <destinationReference><plc4x:verify type="s7:short" 
name="cotp-local-reference"/></destinationReference>
            <!-- Extract the reference the remote would like us to use in this 
session. -->
            <sourceReference><plc4x:extract type="s7:short" 
name="cotp-remote-reference"/></sourceReference>
            <protocolClass>0</protocolClass>
            <parameters>
              <!--
                These elements might be transferred in alternate order, we just 
care about all of them being
                transferred.
              -->
              <plc4x:unordered>
               <parameter>
                  <type>192</type>
                  <parameterLength>1</parameterLength>
                  <CotpParameterTpduSize>
                    <tpduSize><plc4x:extract type="s7:byte" 
name="cotp-tpdu-size"/></tpduSize>
                  </CotpParameterTpduSize>
                </parameter>
                <parameter>
                  <type>193</type>
                  <parameterLength>2</parameterLength>
                  <CotpParameterCallingTsap>
                    <tsapId><plc4x:extract type="s7:short" 
name="cotp-calling-tsap"/></tsapId>
                  </CotpParameterCallingTsap>
                </parameter>
                <parameter>
                  <type>194</type>
                  <parameterLength>2</parameterLength>
                  <CotpParameterCalledTsap>
                    <tsapId><plc4x:extract type="s7:short" 
name="cotp-called-tsap"/></tsapId>
                  </CotpParameterCalledTsap>
                </parameter>
                <!-- The remote might be passing other parameters, we'll just 
ignore them for now -->
                <plc4x:ignore/>
              </plc4x:unordered>
            </parameters>
          </CotpTpduConnectionResponse>
        </userData>
      </s7:tpktMessage>
    </plc4x:receive>
  </onentry>
  <transition cond="" target="sendS7SetupCommunicationRequest"/>
  <transition cond="" target="error"/>
</state>



“s7” is the namespace of my DFDL schema. The default namespace is the namespace 
of SCXML. The “plc4x” namespace is sort of my idea what’s missing.

“insert” would insert some value from an internal context into the template, 
“extract” would take values from the message and save it in the context, 
“verify” would compare the value it reads with one in the context, “ignore” 
would just ignore it and it’s content, “unordered” would sort of allow me to 
expect a sequence of elements, but not necessarily in that order.



If TDML has any form of way to define such a “plc4x:ignore” or 
“plc4x:unordered”, I would really like to use that. At least those are the 
elements I could expect to be useful in something like TDML.



Any ideas/suggestions?



Chris


Reply via email to