以有效方式从 XmlNode 读取/提取值时出现问题



我想从我收到的这个 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";
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

尝试遵循 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:temptest.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;}
    }
}

我更愿意一次性反序列化 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.无论您需要什么,都可以使用自定义逻辑进行提取

希望这有帮助。

最新更新