question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Deserialization stops on empty CDATA element

See original GitHub issue

I have just encountered this bug when deserializing a document consisting mostly of CDATA elements. Some elements were empty and this is where the process would stop. All subsequent elements are ignored.

Excerpt from XML file:

    <Device fb="FB_Pneumatic2Pos" commandStruct="E_Pneumatic_Cmd">
      <Definition><![CDATA[	"#InstanceName#"(PlcCycleTime := "DB_Time".PlcCycleTime,
		OpMode := "DB_#Station#_Station".OpMode,
		Inactive := FALSE,
		I_SensorA := #I_SensorA#,
		I_SensorB := #I_SensorB#,
		C_TwoCoils := #C_TwoCoils#,
		C_ForceVentilate := #C_ForceVentilate#,
		C_Clamping := #C_Clamping#,
		C_PL := "E_PL".#C_PL#,
		C_TimeVentilate := T#200ms,
		C_TimeoutDuration := T#3s,
		C_WaitTimePosA := T#0ms,
		C_WaitTimePosB := T#0ms,
		Q_ValveA => #Q_ValveA#,
		Q_ValveB => #Q_ValveB#,
		Q_ValveOpenClamping => #Q_ValveOpenClamping#);]]></Definition>
      <DeviceDataDb><![CDATA[]]></DeviceDataDb>
      <ServiceHandler><![CDATA[	"FC_Pneumatic2Pos_Service_3Rows"(DeviceNo := #DeviceNo#,
		Row := #Row#,
		RowVisible := TRUE,
		DeviceName_Textlist := "E_Service3Row_DeviceNames"."#DeviceName#",
		ButtonTextPosA_Textlist := "E_Service_ButtonText"."#ActionA#",
		ButtonTextPosB_Textlist := "E_Service_ButtonText"."#ActionB#",
		I_PosA_2 := #I_SensorA2#,
		I_PosB_2 := #I_SensorB2#,
		IDB := #InstanceName#,
		Btn_DeActivateService := "DB_#Station#_Station".Buttons.Service);]]></ServiceHandler>
      <ParameterDb><![CDATA[]]></ParameterDb>
      <Releases><![CDATA[		"#InstanceName#".ReleasePosA := FALSE;
		"#InstanceName#".ReleasePosB := FALSE;]]></Releases>
      <CommandStart><![CDATA[]]></CommandStart>
      <WatchAndForceTable>
        <Capacity>16</Capacity>
        <WatchAndForceTableEntry name="Cmd" />
        <WatchAndForceTableEntry name="Execute" />
        <WatchAndForceTableEntry name="ExecState" />
        <WatchAndForceTableEntry name="ErrorCode" />
        <WatchAndForceTableEntry name="_State[1]" />
        <WatchAndForceTableEntry name="_StateName" />
        <WatchAndForceTableEntry name="I_SensorA" />
        <WatchAndForceTableEntry name="I_SensorB" />
        <WatchAndForceTableEntry name="_ValveA" />
        <WatchAndForceTableEntry name="_ValveB" />
        <WatchAndForceTableEntry name="_ValveOpenClamping" />
      </WatchAndForceTable>
    </Device>

This is the class I have previously serialized to the above XML.

    [DebuggerDisplay("{FB}")]
    [XmlRoot("Device")]
    public class SiemensDeviceTemplate : IDeviceTemplate
    {
        [XmlAttribute("fb")]
        public string FB { get; set; }

        [Verbatim]
        [XmlElement("Definition")]
        public string Definition { get; set; }

        [Verbatim]
        [XmlElement("DeviceDataDb")]
        public string DeviceDataDb { get; set; }

        [XmlElement("PlcTags")]
        public List<PlcTagTemplate> PlcTags { get; set; }

        [Verbatim]
        [XmlElement("ServiceHandler")]
        public string ServiceHandler { get; set; }
       
        [Verbatim]
        [XmlElement("ParameterDb")]
        public string ParameterDb { get; set; }

        [Verbatim]
        [XmlElement(ElementName = "Releases")]
        public string Releases { get; set; }

        [XmlAttribute("commandStruct")]
        public string CommandStruct { get; set; }

        [Verbatim]
        [XmlElement("CommandStart")]
        public string CommandStart { get; set; }

        [XmlElement("WatchAndForceTable")]
        public List<WatchAndForceTableTemplate> WatchAndForceTableEntires { get; set; }
    }

I have dug through the code and in XmlReader.cs method Content(). I have changed the following line to fix it and all tests passed except Issue271Test which seems to be unrelated to this issue.

		public string Content()
		{
			switch (_reader.NodeType)
			{
				case XmlNodeType.Attribute:
					return _reader.Value;
				default:
					if (_reader.IsEmptyElement && _reader.CanReadValueChunk)
					{
						Set();
						return string.Empty;
					}

					var isNull = IsSatisfiedBy(NullValueIdentity.Default);

					if (!isNull)
					{
						_reader.Read();
					}

					var result = isNull ? null : _reader.Value;

					if (!string.IsNullOrEmpty(result) || _reader.NodeType == XmlNodeType.CDATA) // added the node type check
					{
						_reader.Read();
						Set();
					}

					return result;
			}
		}					

Thanks for developing this project. 👍

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
Mike-E-angelocommented, Sep 11, 2020

Hah, that would do it! OK cool one less anomaly to worry about (I was fearing it might be some weird latent threading issue somehow).

Glad everything is to your liking. I will deploy this to NuGet next Tuesday and update here when it’s available. Please continue using the preview-build until that time.

1reaction
ms0815usercommented, Sep 11, 2020

I have reviewed the PR. It’s all good 👍. I also found out why #271 fails on my end. It’s a localisation issue because I ran it on a German system.

  Message: 
    Expected exception message to match the equivalent of 
    "Unknown/invalid member encountered: 'Show'. Line 4, position 7.", but 
    "Unknown/invalid member encountered: 'Show'. Zeile 4, Position 7." does not.
Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Serializing list of nullable CDATA
For some reason, the deserialization stops, after reaching a CDATA value which is null. I have tried creating a private string and creating...
Read more >
Deserialisation terminates silently at element for property marked ...
Deserialize () stops processing the document if it encounters an element that corresponds to a property that is marked with XmlIgnoreAttribute .
Read more >
LSSerializer (Java Platform SE 8 )
A LSSerializer provides an API for serializing (writing) a DOM document out into XML. The XML data is written to a string or...
Read more >
A Roadmap to XML Parsers in Python
In this tutorial, you'll learn what XML parsers are available in Python and how to pick the right parsing model for your specific...
Read more >
[jackson-user] Deserialize whole XML element as a raw String.
Re: [jackson-user] Deserialize whole XML element as a raw String. ... cdata is under key "", empty String, under first location >>> it...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found