views:

266

answers:

2

The HR-XML 3.0 spec provides WSDL's to generate their entities. I'm trying to deserialize their example xml in their documentation, but it's not working.

        Candidate.CandidateType candidate = null;
        string path = "c:\\candidate.xml";
        XmlSerializer serializer = new XmlSerializer(typeof(Candidate.CandidateType), "http://www.hr-xml.org/3");
        StreamReader reader = null;
        reader = new StreamReader(path);
        candidate = (Candidate.CandidateType)serializer.Deserialize(reader);

The error I'm getting:

"<Candidate xmlns='http://www.hr-xml.org/3'&gt; was not expected."

Any suggestions?

Update: I tried XmlSerializing a CandidatePerson element and it looks like it uses CandidatePersonType instead of CandidatePerson. I think I'm doing something wrong here though...

first lines of Candidate.CandidateType (all auto-generated):

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.3082")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.hr-xml.org/3")]
public partial class CandidateType {

    private IdentifierType2 documentIDField;

    private IdentifierType2[] alternateDocumentIDField;

    private string documentSequenceField;
A: 

The following is more of a comment, but it's too long, so I'll put it here.

The CandidateType class is properly decorated with the XmlType attribute. That is an attribute that applies to types, and determines how the type will be emitted in any generated XML Schema. It has nothing to do with the namespace on an element that happens to have the same type.

Consider the following C# code:

public class CandidateType {}

public class Foo
{
    CandidateType _candidate1;
    CandidateType _candidate2;
}

Note that you can have multiple variables of the same type. In the same way, you could have:

<xs:element name="Candidate1" type="hrx:CandidateType"/>
<xs:element name="Candidate2" type="hrx:CandidateType"/>

These are two elements which will validate against the same type definition, but which are otherwise unrelated. If they are in the same XML Schema, then they will be in the same namespace. But what if they're not? Then you could have an instance document like:

<ns1:Candidate1 xmlns:ns1="namespace1" xmlns="http://www.hr-xml.org/3"&gt; ... </ns1:Candidate1>
<ns2:Candidate2 xmlns:ns2="namespace2" xmlns="http://www.hr-xml.org/3"&gt; ... </ns1:Candidate2>

What you need to do is specify the namespace of the Candidate element to the XML Serializer. The fact that the CandidateType type is in a particular namespace does not determine the namespace of the Candidate element.

John Saunders
Ok I think I get what you're saying. How would i determine the namespace for the Candidate element?Thanks!
Drakarian
I've tried using the http://www.hr-xml.org/3 as the namespace for the XmlSerializer but I get the same errors.
Drakarian
A: 

Muahaha I figured it out finally!

John Saunders was right, I needed to specify the default namespace in the XmlSerializer, but in addition to that I have to specify the XmlRootAttribute because the Class that I'm trying to de-serialize to does not have the same name as the root element.

Here is my code for de-serializing the HR-XML ProcessCandidate example:

    protected static ImportTest.CandidateService.ProcessCandidateType DeserializeProcessCandidate(string path)
    {
        CandidateService.ProcessCandidateType processCandidate = null;
        XmlRootAttribute root = new XmlRootAttribute("ProcessCandidate");
        XmlSerializer serializer = new XmlSerializer(typeof(CandidateService.ProcessCandidateType), new XmlAttributeOverrides(), new Type[0], root, "http://www.hr-xml.org/3");
        StreamReader reader = null;

        try
        {
            reader = new StreamReader(path);
            processCandidate = (CandidateService.ProcessCandidateType)serializer.Deserialize(reader);
            reader.Close();
        }
        catch (Exception ex)
        {
            reader.Close();
            throw (new Exception(ex.InnerException.Message));
        }

        return processCandidate;
    }

Thanks for the help John!

Drakarian