C
C#2y ago
Pold

❔ Help deserializing XML file

Hello, I've been trying to deserialize the following XML, using System.Xml, no external libraries:
<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:ns1='urn:WsLMEInet'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:SOAP-ENC='http://schemas.xmlsoap.org/soap/encoding/'
SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
<SOAP-ENV:Body>
<ns1:LMEEvenFecResponse>
<LMEEvenFecReturn xsi:type='ns1:LMEEvenFecResponse'>
<Estado xsi:type='xsd:integer'>0</Estado>
<GloEstado xsi:type='xsd:string'>Sin Error</GloEstado>
<ListaLicencias SOAP-ENC:arrayType='ns1:LicenciaType[139]' xsi:type='ns1:ListaLicenciasType'>
<item xsi:type='ns1:LicenciaType'>
<NumLicencia xsi:type='xsd:integer'>2780337</NumLicencia>
<DigLicencia xsi:type='xsd:string'>7</DigLicencia>
<estado xsi:type='xsd:integer'>1</estado>
<fecha xsi:type='xsd:dateTime'>2023-01-04T15:47:17</fecha>
</item>
<item xsi:type='ns1:LicenciaType'>
<NumLicencia xsi:type='xsd:integer'>2780338</NumLicencia>
<DigLicencia xsi:type='xsd:string'>5</DigLicencia>
<estado xsi:type='xsd:integer'>1</estado>
<fecha xsi:type='xsd:dateTime'>2023-01-04T15:47:18</fecha>
</item>
</ListaLicencias>
</LMEEvenFecReturn>
</ns1:LMEEvenFecResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:ns1='urn:WsLMEInet'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:SOAP-ENC='http://schemas.xmlsoap.org/soap/encoding/'
SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
<SOAP-ENV:Body>
<ns1:LMEEvenFecResponse>
<LMEEvenFecReturn xsi:type='ns1:LMEEvenFecResponse'>
<Estado xsi:type='xsd:integer'>0</Estado>
<GloEstado xsi:type='xsd:string'>Sin Error</GloEstado>
<ListaLicencias SOAP-ENC:arrayType='ns1:LicenciaType[139]' xsi:type='ns1:ListaLicenciasType'>
<item xsi:type='ns1:LicenciaType'>
<NumLicencia xsi:type='xsd:integer'>2780337</NumLicencia>
<DigLicencia xsi:type='xsd:string'>7</DigLicencia>
<estado xsi:type='xsd:integer'>1</estado>
<fecha xsi:type='xsd:dateTime'>2023-01-04T15:47:17</fecha>
</item>
<item xsi:type='ns1:LicenciaType'>
<NumLicencia xsi:type='xsd:integer'>2780338</NumLicencia>
<DigLicencia xsi:type='xsd:string'>5</DigLicencia>
<estado xsi:type='xsd:integer'>1</estado>
<fecha xsi:type='xsd:dateTime'>2023-01-04T15:47:18</fecha>
</item>
</ListaLicencias>
</LMEEvenFecReturn>
</ns1:LMEEvenFecResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I haven't been able to get this value SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'. Some help would be great.
71 Replies
Pold
PoldOP2y ago
I tried several possible solutions in a testing code like this:
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlAttribute(AttributeName = "encodingStyle", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public string EncodingStyle { get; set; }
[XmlElement(ElementName = "Body")]
public Body Body { get; set; }
}
// Omitting the rest of the code, you already get the idea

public static void Main()
{
var serializerNamespaces = new XmlSerializerNamespaces();
serializerNamespaces.Add("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
serializerNamespaces.Add("ns1", "urn:WsLMEInet");
serializerNamespaces.Add("xsd", "http://www.w3.org/2001/XMLSchema");
serializerNamespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");

// Deserialize
var xmlSerializer = new XmlSerializer(typeof(Envelope));
using var xmlStream = new FileStream("example.xml", FileMode.Open);
var myEnvelope = (Envelope)xmlSerializer.Deserialize(xmlStream);

// Serialize
var writer = new StreamWriter(Console.OpenStandardOutput());
writer.AutoFlush = true;
Console.SetOut(writer);

xmlSerializer.Serialize(writer, myEnvelope, serializerNamespaces);
writer.Close();
}
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlAttribute(AttributeName = "encodingStyle", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public string EncodingStyle { get; set; }
[XmlElement(ElementName = "Body")]
public Body Body { get; set; }
}
// Omitting the rest of the code, you already get the idea

public static void Main()
{
var serializerNamespaces = new XmlSerializerNamespaces();
serializerNamespaces.Add("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
serializerNamespaces.Add("ns1", "urn:WsLMEInet");
serializerNamespaces.Add("xsd", "http://www.w3.org/2001/XMLSchema");
serializerNamespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");

// Deserialize
var xmlSerializer = new XmlSerializer(typeof(Envelope));
using var xmlStream = new FileStream("example.xml", FileMode.Open);
var myEnvelope = (Envelope)xmlSerializer.Deserialize(xmlStream);

// Serialize
var writer = new StreamWriter(Console.OpenStandardOutput());
writer.AutoFlush = true;
Console.SetOut(writer);

xmlSerializer.Serialize(writer, myEnvelope, serializerNamespaces);
writer.Close();
}
JakenVeina
JakenVeina2y ago
all looks okay to me is Body deserializing? better question: is EncodingStyle deserializing?
Pold
PoldOP2y ago
its not its always null I haven't been able to get that SOAP-ENV:encodingStyle value at all I have a break point after deserializing, so I always check, no result 😦
JakenVeina
JakenVeina2y ago
how do you k ow it's null? er scratch that so, yeah, is Body null?
Pold
PoldOP2y ago
nope, body is not null
JakenVeina
JakenVeina2y ago
are you quite certain you're deserializing the right file?
Pold
PoldOP2y ago
yes its the only xml file on the project (console project I made, with the only purpose of solving this problem)
JakenVeina
JakenVeina2y ago
well, now I have to ask if it's part of the project which copy of the file are you deserializing?
Pold
PoldOP2y ago
JakenVeina
JakenVeina2y ago
that screenshot is incomprehensible
Pold
PoldOP2y ago
what I meant sending the screenshot, its that its quite a simple project, Program.cs with the code, and example.xml
JakenVeina
JakenVeina2y ago
yes which copy of example.xml?
Pold
PoldOP2y ago
what do mean which copy? there is only 1 version of the xml
JakenVeina
JakenVeina2y ago
if you have it as part of your project, it's likely getting copied and deployed to the bin folder especially if you're referencing it via a relative path
Pold
PoldOP2y ago
oh I get it, 1 sec
JakenVeina
JakenVeina2y ago
it's likely opening the version in the bin folder, which may not be the one you've been editing
Pold
PoldOP2y ago
there is no copy of example.xml on bin nor obj
JakenVeina
JakenVeina2y ago
how are you running the project, then? how does that relative path of "example.xml" resolve?
Pold
PoldOP2y ago
let me delete these folders and try again, I recycled this project and have some leftovers 1 min
JakenVeina
JakenVeina2y ago
by default, that means it's going to look for the file in the same folder as the project exe/dll which is the bin folder unless you're changing the working directory, or launching the program from a different directory
Pold
PoldOP2y ago
I'm just using the default debugging tool on vscode
Pold
PoldOP2y ago
Pold
PoldOP2y ago
clean project
JakenVeina
JakenVeina2y ago
well, I know nothing about VSCode tooling
Pold
PoldOP2y ago
Pold
PoldOP2y ago
it doesnt generate a xml copy
JakenVeina
JakenVeina2y ago
also, obligatory recommendation to notbuse VSCode, if you don't have to
Pold
PoldOP2y ago
uses the same one I have in the root folder
JakenVeina
JakenVeina2y ago
alright, well that's really the only idea I have your code looks proper obviously, it's not, and it's almost certainly that you're not defining namespaces properly, somehow
Pold
PoldOP2y ago
yeah, it "looks" proper.. but I just can't read that damn namespaced attribute
JakenVeina
JakenVeina2y ago
but I don't see it maybe because the namespace alias is at the same level as the attribute that's trying to use it? does it work if you drop the namespace on the attribute? or if you swap the namespace definition in your model to just SOAP-ENV? maybe the engine just doesn't donnamespace translations for you? I would be rather appalled if it didn't, but maybe not surprised
Pold
PoldOP2y ago
Same result, null
JakenVeina
JakenVeina2y ago
dropped from both the file and the model, right?
Pold
PoldOP2y ago
only model same, null
JakenVeina
JakenVeina2y ago
yeah, that's definitely not gonna work, the namespaces now don't match. Drop it from both
Pold
PoldOP2y ago
do you mean delete it from example.xml ?
JakenVeina
JakenVeina2y ago
yes
Pold
PoldOP2y ago
that wouldn't make much sense, I can't edit that file, since it comes from an API 😦 ill try tho, second
JakenVeina
JakenVeina2y ago
I'm aware, we're just experimenting additional idea: deserialize the whole thing to an XmlDocument or whatever the DOM library is, and you can inspect EXACTLY how the engine is interpreting everything
Pold
PoldOP2y ago
it actually didnt work 😦
Pold
PoldOP2y ago
JakenVeina
JakenVeina2y ago
weird
Pold
PoldOP2y ago
Pold
PoldOP2y ago
Pold
PoldOP2y ago
now, THAT makes no sense
JakenVeina
JakenVeina2y ago
little bit
Pold
PoldOP2y ago
I assumed it would work.
JakenVeina
JakenVeina2y ago
now I'm intrigued and wanna get my own hands on this unfortunately, I'm not at home
Pold
PoldOP2y ago
yeah, thanks for the help. Much appreciated... this new finding can give me some room to test some new things.... there are way more examples of xml deserialization when the attribute has no namespace, maybe I can make it work, then I go back to try it with namespace My bad, I didn't correctly change the example.xml file. since the code was running. It worked now (without namespace)
Pold
PoldOP2y ago
Pold
PoldOP2y ago
Adding the namespace back, it goes back to null
JakenVeina
JakenVeina2y ago
well, that's something
Mayor McCheese
Did you try pasting xml as classes?
Pold
PoldOP2y ago
Im not familiar with the concept, what do you mean?
Pold
PoldOP2y ago
It seems I needed to specify Form = System.Xml.Schema.XmlSchemaForm.Qualified and now it is not null. Thanks a lot, that tool helped me find that problem. Its not perfect tho, now it throws another problem. Gotta check that out and ill post here again (maybe later/tomorrow)
JakenVeina
JakenVeina2y ago
so, you need an extra annotation to tell the deserializer to interpret namespaces in attribute names?
Mayor McCheese
Xml serialization can get really special really fast Usually I just paste xml as classes and that gets me most | all of the way there
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Pold
PoldOP2y ago
I was kinda busy and couldn't come back to ask my new problem. The thing is, I don't really knwo how to deserialize this part:
Pold
PoldOP2y ago
Paste XML as Classes doesn't work on this part, and when deserializing LMEEvenFecReturn it throws an error
Pold
PoldOP2y ago
Mayor McCheese
Where are you getting the soap from?
Pold
PoldOP2y ago
It's a private company, they serve this api service for all their clients, the thing is, it's access restricted tho, I have that xml example, but can't really test it on realtime I guess you wanted me to use the utility you posted above
Mayor McCheese
Yah I'm not in a great spot right now, but I think you posted the soap right?
JakenVeina
JakenVeina2y ago
that seems highly sus cyclical references?
public class LMEEvenFecResponse
{
public LMEEvenFecResponse LMEEvenFecReturn { get; set; }
}
public class LMEEvenFecResponse
{
public LMEEvenFecResponse LMEEvenFecReturn { get; set; }
}
actually more like actually, I just don't know off-hand haven't done XML serialization in this detail in a long time dunno why the class generator tool is throwing an error, might be worth submitting a bug report ultimately, I believe what's happening is that you have a property or something of type LMEEvenFecReturn, which is only a base/abstract class. LMEEvenFecResponse is annotated as the specific subclass that was serialized, so that annotation there is telling the deserializer what class to new up an instance of and there's some kinda bug or limitation in the code-generator tool causing the issue, while the XML itself is fine I mean, irrelevant of what the tag is supposed to be there for the error is nonsense the type ns1:LMEEvenFecResponse is clearly defined, in the exact same screenshot
Mayor McCheese
Iirc the soap stuff does some horrifying stuff
JakenVeina
JakenVeina2y ago
for sure it SEEMS to me what's happening here is that responses can be nested which is perfectly fine, OOP-wise like how exceptions can have an inner exception
Mayor McCheese
Only only looked at the xml as a giant wall of text tbh
Pold
PoldOP2y ago
Thanks for the help, haven't really got it to work. I was trying to work around it by defining LMEEvenFecResponse as an array of 1 element, where LMEEvenFecReturn is a derived class. Something like it appears in the documentation: https://learn.microsoft.com/en-us/dotnet/standard/serialization/controlling-xml-serialization-using-attributes#serializing-derived-classes I hope I get it to work like that... still no success tho, that type having a namespace kinda bothers me, however didn't have much time today to try.
Controlling XML Serialization Using Attributes
Attributes can be used to control the XML serialization of an object or to create an alternate XML stream from the same set of classes.
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server