Search code examples
c#jsonxmlazure-cosmosdbinfopath

XML conversion to Json and DeserializeObject issue - InfoPath namespaces?


I am looking into loading a large number of InfoPath XML files into Cosmos DB as Json files to test a possible project. But I am struggling with converting the XML files to Json and then loading back into a c# class. I think this is related to the namespace that InfoPath puts into the XML but I'm not sure. I thought at first I should try to remove all the namespace references from the XML but now I'm wondering if I just need to work more on the definition of the class file. To generate the class file I used Visual Studio "paste as Json". I assumed after loading the XML, saving to Json, then using that as the basis for the new class file, I could load right back into the object but when I call DeserializeObject it always ends up null.

Is this because the class file definition needs to be changed or should I instead look to try and clean the XML prior to converting to Json?

Sample XML

<?xml version="1.0" encoding="utf-8"?>
<?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:myProject:-myXSD-2017-05-05T14-19-13" solutionVersion="1.0.0.2046" productVersion="16.0.0.0" PIVersion="1.0.0.0" href="https://myportal.sharepoint.com/sites/mySite/myProject/Forms/template.xsn"?>
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.4"?>
<?mso-infoPath-file-attachment-present?>
<my:myFields xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2017-05-05T14:19:13" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:pc="http://schemas.microsoft.com/office/infopath/2007/PartnerControls" xmlns:ma="http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes" xmlns:d="http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields" xmlns:q="http://schemas.microsoft.com/office/infopath/2009/WSSList/queryFields" xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution" xmlns:dms="http://schemas.microsoft.com/office/2009/documentManagement/types" xmlns:tns="http://microsoft.com/webservices/SharePointPortalServer/UserProfileService" xmlns:s1="http://microsoft.com/wsdl/types/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" xml:lang="en-US">
    <my:Admin>
        <my:Routing_Order>
            <my:Approver-1_Order>1</my:Approver-1_Order>
            <my:Approver-2_Order>5</my:Approver-2_Order>
            <my:Approver-3_Order>4</my:Approver-3_Order>
        </my:Routing_Order>
    </my:Admin>
    <my:Request_Status>Save as Draft</my:Request_Status>
    <my:Request_Type>CAPEX</my:Request_Type>
</my:myFields>

Class file

namespace xml_to_json
{

    public class Rootobject
    {
        public MyMyfields mymyFields { get; set; }
    }

    public class MyMyfields
    {
        public string xmlnsmy { get; set; }
        public string xmlnsxsi { get; set; }
        public string xmlnsxhtml { get; set; }
        public string xmlnspc { get; set; }
        public string xmlnsma { get; set; }
        public string xmlnsd { get; set; }
        public string xmlnsq { get; set; }
        public string xmlnsdfs { get; set; }
        public string xmlnsdms { get; set; }
        public string xmlnstns { get; set; }
        public string xmlnss1 { get; set; }
        public string xmlnshttp { get; set; }
        public string xmlnstm { get; set; }
        public string xmlnssoap { get; set; }
        public string xmlnssoapenc { get; set; }
        public string xmlnsmime { get; set; }
        public string xmlnssoap12 { get; set; }
        public string xmlnswsdl { get; set; }
        public string xmlnsxd { get; set; }
        public string xmllang { get; set; }
        public MyAdmin myAdmin { get; set; }
        public string myRequest_Status { get; set; }
        public string myRequest_Type { get; set; }
    }

    public class MyAdmin
    {
        public MyRouting_Order myRouting_Order { get; set; }
    }

    public class MyRouting_Order
    {
        public string myApprover1_Order { get; set; }
        public string myApprover2_Order { get; set; }
        public string myApprover3_Order { get; set; }
    }


}

Console test code

namespace xml_to_json
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument myDoc = new XmlDocument();
            string sourcedir = @"C:\Users\mystuff\Downloads\test-clean\";
            string xmlfilein = @"test";
            string xmlfile = string.Concat(sourcedir, xmlfilein, ".xml");
            string jsonfileout = string.Concat(sourcedir, xmlfilein, ".json");
            myDoc.Load(xmlfile);
            string jsonText = JsonConvert.SerializeXmlNode(myDoc.LastChild);
            File.WriteAllText(jsonfileout, jsonText);

            Rootobject obj = new Rootobject();
            obj = JsonConvert.DeserializeObject<Rootobject>(jsonText);
            Console.WriteLine(obj.mymyFields.myRequest_Status);   
        }   
    }
}

Solution

  • Try code below using xml linq :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(FILENAME);
    
                XElement routingOrder = doc.Descendants().Where(x => x.Name.LocalName == "Routing_Order").FirstOrDefault();
    
                Dictionary<string, string> orders = routingOrder.Elements()
                    .GroupBy(x => x.Name.LocalName, y => (string)y)
                    .ToDictionary(x => x.Key, y => y.FirstOrDefault());
    
                string status = (string)doc.Descendants().Where(x => x.Name.LocalName == "Request_Status").FirstOrDefault();
                string requestType = (string)doc.Descendants().Where(x => x.Name.LocalName == "Request_Type").FirstOrDefault();
            }
        }
    }