以有效方式从XmlNode读取/提取值的问题

时间:2019-01-17 15:58:42

标签: c# xml

我想从收到的xml响应中提取信息,但是遇到问题。

我相信我当前的代码效率不高,因为我必须编写很多if语句来提取数据。

基本上,我想遍历元素并将所需的值存储在变量中,稍后将在代码中使用。

有人可以建议我尝试实现的更好的选择吗?

这是我收到的XML响应:

 <?xml version="1.0"?>
<gls:TheDocument xmlns:pbr="http://www.something.com" xmlns:gls="http://www.testsomething.com" xmlns:cnr="http://www.organisation.com" 
xmlns:h="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaVersion="2.8">
<gls:PatientDem>
            <cnr:PatientId>
                <cnr:IdValue>123455</cnr:IdValue>
                <cnr:IdScheme>TEST</cnr:IdScheme>
                <cnr:IdType>PRN</cnr:IdType>
            </cnr:PatientId>
            <cnr:PatientName>
                <cnr:Name>
                    <cnr:Title>Mr</cnr:Title>
                    <cnr:GivenName>Joe</cnr:GivenName>
                    <cnr:FamilyName>Wood</cnr:FamilyName>
                </cnr:Name>
                <cnr:NameType>Current Name</cnr:NameType>
            </cnr:PatientName>
            <cnr:PatientAddress>
                <cnr:Address>
                    <cnr:AddressLine>57 High Street</cnr:AddressLine>
                    <cnr:AddressLine>London</cnr:AddressLine>
                </cnr:Address>
                <cnr:PostCode>WC1E 7HU</cnr:PostCode>
                <cnr:AddressType>Current Residence</cnr:AddressType>
            </cnr:PatientAddress>
            <cnr:DateOfBirth>1969-11-02</cnr:DateOfBirth>
            <cnr:Sex>M</cnr:Sex>
        </gls:PatientDem>
</gls:TheDocument>

这是C#

        XmlDocument xml = new XmlDocument();
        xml.Load(responseXML);

        XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable);
        nsmgr.AddNamespace("gls", "http://www.testsomething.com");
        nsmgr.AddNamespace("cnr", "http://www.organisation.com");

        XmlNodeList list = xml.SelectNodes("//gls:PatientDem", nsmgr);

        string idType = string.Empty;
        string idScheme = string.Empty;
        string idValue = string.Empty;

        string title = string.Empty;
        string givenName = string.Empty;
        string familyName = string.Empty;
        string nameType = string.Empty;

        string addressLine = string.Empty;
        string postCode = string.Empty;
        string addressType = string.Empty;
        DateTime dateOfBirth;
        string gender = string.Empty;

        string gpName = string.Empty;
        string gpAddressLine = string.Empty;
        string gpPostCode = string.Empty;
        string gpAddressType = string.Empty;

        foreach (XmlNode xmlNode in list)
        {
            //Root Node Patient
            if (xmlNode.HasChildNodes)
            {
                foreach (XmlNode childNode in xmlNode.ChildNodes)
                {
                    if (childNode.HasChildNodes)
                    {
                        foreach (XmlNode node in childNode.ChildNodes)
                        {
                            if (node.HasChildNodes)
                            {
                                foreach (XmlNode innerChildNode in node.ChildNodes)
                                {
                                    if (innerChildNode.LocalName == "AddressLine" && childNode.LocalName == "PatientAddress")
                                    {
                                        if (addressLine.Length > 0)
                                        {
                                            addressLine += "," + innerChildNode.InnerText;
                                        }
                                        else
                                        {
                                            addressLine = innerChildNode.InnerText;
                                        }
                                    }

                                    switch (innerChildNode.LocalName)
                                    {
                                        case "Title":
                                            title = innerChildNode.InnerText;
                                            break;
                                        case "GivenName":
                                            givenName = innerChildNode.InnerText;
                                            break;
                                        case "FamilyName":
                                            familyName = innerChildNode.InnerText;
                                            break;
                                        default:
                                            break;
                                    }

                                    if (innerChildNode.LocalName == "#text")
                                    {
                                        var parentNode = innerChildNode.ParentNode;

                                        switch (parentNode.LocalName)
                                        {
                                            case "IdValue":
                                                idValue = node.InnerText;
                                                break;
                                            case "IdScheme":
                                                idScheme = node.InnerText;
                                                break;
                                            case "IdType":
                                                idType = node.InnerText;
                                                break;
                                            case "NameType":
                                                nameType = node.InnerText;
                                                break;
                                            case "PostCode":
                                                postCode = node.InnerText;
                                                break;
                                            case "AddressType":
                                                addressType = node.InnerText;
                                                break;
                                            default:
                                                break;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (childNode.LocalName == "DateOfBirth")
                                {
                                    dateOfBirth = Convert.ToDateTime(childNode.InnerText);
                                }

                                if (childNode.LocalName == "Sex")
                                {
                                    if (childNode.InnerText == "M")
                                    {
                                        gender = "Male";
                                    }
                                    else if (childNode.InnerText == "F")
                                    {
                                        gender = "Female";
                                    }
                                }
                            }

                        }
                    }

                }
            }
        }

2 个答案:

答案 0 :(得分:1)

尝试关注Xml Linq。我正在从文件中读取xml并放入字符串中。您可以改用您的响应字符串。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace ConsoleApplication97
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml"; 
        static void Main(string[] args)
        {
            string xml = File.ReadAllText(FILENAME);

            XDocument doc = XDocument.Parse(xml);
            XElement root = doc.Root;
            XNamespace glsNs = root.GetNamespaceOfPrefix("gls");
            XNamespace cnrNs = root.GetNamespaceOfPrefix("cnr");

            List<XElement> xPatientDems = doc.Descendants(glsNs + "PatientDem").ToList();

            List<PatientDem> patientDems = new List<PatientDem>();
            foreach (XElement xPatientDem in xPatientDems)
            {
                PatientDem patientDem = new PatientDem();
                patientDems.Add(patientDem);

                XElement xPatientId = doc.Descendants(cnrNs + "PatientId").FirstOrDefault();
                patientDem.patientId = (string)xPatientId.Element(cnrNs + "IdValue");
                patientDem.patientIdScheme = (string)xPatientId.Element(cnrNs + "IdScheme");
                patientDem.patientIdType = (string)xPatientId.Element(cnrNs + "IdType");

                XElement xPatientName = doc.Descendants(cnrNs + "PatientName").FirstOrDefault();
                patientDem.title = (string)xPatientName.Descendants(cnrNs + "Title").FirstOrDefault();
                patientDem.givenName = (string)xPatientName.Descendants(cnrNs + "GivenName").FirstOrDefault();
                patientDem.familyName = (string)xPatientName.Descendants(cnrNs + "FamilyName").FirstOrDefault();
                patientDem.nameType = (string)xPatientName.Descendants(cnrNs + "NameType").FirstOrDefault();

                XElement xPatientAddress = doc.Descendants(cnrNs + "PatientAddress").FirstOrDefault();
                patientDem.addrressLine = xPatientAddress.Descendants(cnrNs + "AddressLine").Select(x => (string)x).ToList();
                patientDem.postCode = (string)xPatientAddress.Element(cnrNs + "PostCode");
                patientDem.addressType = (string)xPatientAddress.Element(cnrNs + "AddressType");

                patientDem.dateOfBirth = (DateTime)xPatientDem.Element(cnrNs + "DateOfBirth");
                patientDem.sex = (string)xPatientDem.Element(cnrNs + "Sex");

            }
        }
    }
    public class PatientDem
    {

       public string patientId { get;set;}
       public string patientIdScheme { get;set;}
       public string patientIdType { get;set;}

       public string title { get;set;}
       public string givenName { get;set;}
       public string familyName { get;set;}
       public string nameType { get; set; }

       public List<string> addrressLine { get;set;}
       public string postCode { get;set;}
       public string addressType { get;set;}

       public DateTime dateOfBirth { get;set;}
       public string sex { get;set;}
    }

}

答案 1 :(得分:0)

我希望一次性地反序列化XML,如下面的代码所示。

1。生成保存反序列化XML所需的类

首先从xml生成XSD-

D:\temp>xsd test.xml

然后从xsd生成c#类-

D:\temp>xsd test.xsd /classes

2。反序列化为C#对象

MySerializableClass myObject;  

// Construct an instance of the XmlSerializer with the type  
// of object that is being deserialized.  
XmlSerializer mySerializer =  new XmlSerializer(typeof(MySerializableClass));  

// To read the file, create a FileStream.  
FileStream myFileStream =  new FileStream("myFileName.xml", FileMode.Open);  


// Call the Deserialize method and cast to the object type.  
myObject = (MySerializableClass)mySerializer.Deserialize(myFileStream)

3。无论您需要什么,都可以使用自定义逻辑进行提取

希望这会有所帮助。