C
C#14mo 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
Pold14mo 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
JakenVeina14mo ago
all looks okay to me is Body deserializing? better question: is EncodingStyle deserializing?
Pold
Pold14mo 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
JakenVeina14mo ago
how do you k ow it's null? er scratch that so, yeah, is Body null?
Pold
Pold14mo ago
nope, body is not null
JakenVeina
JakenVeina14mo ago
are you quite certain you're deserializing the right file?
Pold
Pold14mo ago
yes its the only xml file on the project (console project I made, with the only purpose of solving this problem)
JakenVeina
JakenVeina14mo ago
well, now I have to ask if it's part of the project which copy of the file are you deserializing?
Pold
Pold14mo ago
JakenVeina
JakenVeina14mo ago
that screenshot is incomprehensible
Pold
Pold14mo ago
what I meant sending the screenshot, its that its quite a simple project, Program.cs with the code, and example.xml
JakenVeina
JakenVeina14mo ago
yes which copy of example.xml?
Pold
Pold14mo ago
what do mean which copy? there is only 1 version of the xml
JakenVeina
JakenVeina14mo 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
Pold14mo ago
oh I get it, 1 sec
JakenVeina
JakenVeina14mo ago
it's likely opening the version in the bin folder, which may not be the one you've been editing
Pold
Pold14mo ago
there is no copy of example.xml on bin nor obj
JakenVeina
JakenVeina14mo ago
how are you running the project, then? how does that relative path of "example.xml" resolve?
Pold
Pold14mo ago
let me delete these folders and try again, I recycled this project and have some leftovers 1 min
JakenVeina
JakenVeina14mo 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
Pold14mo ago
I'm just using the default debugging tool on vscode
Pold
Pold14mo ago
Pold
Pold14mo ago
clean project
JakenVeina
JakenVeina14mo ago
well, I know nothing about VSCode tooling
Pold
Pold14mo ago
Pold
Pold14mo ago
it doesnt generate a xml copy
JakenVeina
JakenVeina14mo ago
also, obligatory recommendation to notbuse VSCode, if you don't have to
Pold
Pold14mo ago
uses the same one I have in the root folder
JakenVeina
JakenVeina14mo 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
Pold14mo ago
yeah, it "looks" proper.. but I just can't read that damn namespaced attribute
JakenVeina
JakenVeina14mo 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
Pold14mo ago
Same result, null
JakenVeina
JakenVeina14mo ago
dropped from both the file and the model, right?
Pold
Pold14mo ago
only model same, null
JakenVeina
JakenVeina14mo ago
yeah, that's definitely not gonna work, the namespaces now don't match. Drop it from both
Pold
Pold14mo ago
do you mean delete it from example.xml ?
JakenVeina
JakenVeina14mo ago
yes
Pold
Pold14mo ago
that wouldn't make much sense, I can't edit that file, since it comes from an API 😦 ill try tho, second
JakenVeina
JakenVeina14mo 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
Pold14mo ago
it actually didnt work 😦
Pold
Pold14mo ago
JakenVeina
JakenVeina14mo ago
weird
Pold
Pold14mo ago
Pold
Pold14mo ago
Pold
Pold14mo ago
now, THAT makes no sense
JakenVeina
JakenVeina14mo ago
little bit
Pold
Pold14mo ago
I assumed it would work.
JakenVeina
JakenVeina14mo ago
now I'm intrigued and wanna get my own hands on this unfortunately, I'm not at home
Pold
Pold14mo 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
Pold14mo ago
Pold
Pold14mo ago
Adding the namespace back, it goes back to null
JakenVeina
JakenVeina14mo ago
well, that's something
Mayor McCheese
Mayor McCheese14mo ago
Did you try pasting xml as classes?
Pold
Pold14mo ago
Im not familiar with the concept, what do you mean?
Pold
Pold14mo 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
JakenVeina14mo ago
so, you need an extra annotation to tell the deserializer to interpret namespaces in attribute names?
Mayor McCheese
Mayor McCheese14mo ago
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
Accord14mo 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
Pold13mo 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
Pold13mo ago
Paste XML as Classes doesn't work on this part, and when deserializing LMEEvenFecReturn it throws an error
Pold
Pold13mo ago
Mayor McCheese
Mayor McCheese13mo ago
Where are you getting the soap from?
Pold
Pold13mo 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
Mayor McCheese13mo ago
Yah I'm not in a great spot right now, but I think you posted the soap right?
JakenVeina
JakenVeina13mo 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
Mayor McCheese13mo ago
Iirc the soap stuff does some horrifying stuff
JakenVeina
JakenVeina13mo 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
Mayor McCheese13mo ago
Only only looked at the xml as a giant wall of text tbh
Pold
Pold13mo 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
Accord13mo 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.