Deserialization stops on empty CDATA element
See original GitHub issueI 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:
- Created 3 years ago
- Comments:5 (3 by maintainers)
Top 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 >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
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.
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.