【问题标题】:XML same node but different id read method requiredXML 相同的节点但需要不同的 id 读取方法
【发布时间】:2017-06-19 03:39:04
【问题描述】:

我需要一个简单的节点解析技术。我已经阅读了 node.attribute 和 node.innertext。如果您了解 Visual Studio C#.net,请提供帮助。

这是我的代码:

<abc>
    <Limits>
        <Row>
            <LimitId>101</LimitId>
            <Max>10000</Max>
            <Current>0</Current>
        </Row>
        <Row>
            <LimitId>102</LimitId>
            <Max>6000</Max>
            <Current>0</Current>
        </Row>
        <Row>
            <LimitId>109</LimitId>
            <Max>25000</Max>
            <Current>0</Current>
        </Row>
        <Row>
            <LimitId>200</LimitId>
            <Max>45000</Max>
            <Current>0</Current>
        </Row>
    </Limits>
</abc>

【问题讨论】:

  • 谢谢,我试过了,如下: foreach (XmlNode node in doc.GetElementsByTagName("LimitId")) AcctNo = node.InnerText.Substring(0, node.InnerText.Length);跨度>
  • 另一种方法是:foreach (XmlNode node in doc.GetElementsByTagName("Response")) { string LogonId = node.Attributes["Challengekey"].Value;字符串 XId = node.Attributes["XId"].Value; }
  • 我想要 LimitId by Max 和所选 LimitId 的当前值
  • edit您的问题以显示您的代码(粘贴后,突出显示并点击{} 按钮)。代码在 cmets 中不可读。

标签: c# xml visual-studio xml-parsing


【解决方案1】:

这个小例子做了以下事情:

  1. 将 xml 字符串反序列化为类型化对象的实例 (LimitCollection)
  2. 演示迭代所有限制并将其值输出到控制台
  3. 通过 LINQ 方法 FirstOrDefault 使用它的 id 查找特定的 Limit 记录

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Xml.Serialization;
    
    namespace ConsoleApplication11
    {
        class Program
        {
            static void Main(string[] args)
            {
                string xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
                <abc>
                   <Limits>
                        <Row>
                            <LimitId>101</LimitId>
                            <Max>10000</Max>
                            <Current>0</Current>
                        </Row>
                        <Row>
                            <LimitId>102</LimitId>
                            <Max>6000</Max>
                            <Current>0</Current>
                        </Row>
                        <Row>
                            <LimitId>109</LimitId>
                            <Max>25000</Max>
                            <Current>0</Current>
                        </Row>
                        <Row>
                            <LimitId>200</LimitId>
                            <Max>45000</Max>
                            <Current>0</Current>
                        </Row>
                    </Limits>
                </abc>";
    
                XmlSerializer d = new XmlSerializer(typeof(LimitCollection));
                LimitCollection deserializedXml = (LimitCollection)d.Deserialize(new StringReader(xml));
    
                Console.WriteLine("Iterating all limits:");
                foreach (Limit lim in deserializedXml.Limits)
                {
                    Console.WriteLine($"LimitId: {lim.LimitId}, Current: {lim.Current}, Max: {lim.Max}");
                }
    
                Console.WriteLine();
                Limit particularLimit = deserializedXml.Limits.FirstOrDefault(l => l.LimitId == 109);
                if (particularLimit != null)
                {
                    Console.WriteLine($"Particular limit: {particularLimit.LimitId}, Current: {particularLimit.Current}, Max: {particularLimit.Max}");
                }
    
                Console.WriteLine("Press any key to finish...");
                Console.ReadKey();
            }
        }
    
    
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false, ElementName = "abc")]
        public partial class LimitCollection
        {
    
            private Limit[] limitsField;
    
            /// <remarks/>
            [System.Xml.Serialization.XmlArrayItemAttribute("Row", IsNullable = false)]
            public Limit[] Limits
            {
                get
                {
                    return this.limitsField;
                }
                set
                {
                    this.limitsField = value;
                }
            }
        }
    
        /// <remarks/>
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        public partial class Limit
        {
    
            private byte limitIdField;
    
            private ushort maxField;
    
            private byte currentField;
    
            /// <remarks/>
            public byte LimitId
            {
                get
                {
                    return this.limitIdField;
                }
                set
                {
                    this.limitIdField = value;
                }
            }
    
            /// <remarks/>
            public ushort Max
            {
                get
                {
                    return this.maxField;
                }
                set
                {
                    this.maxField = value;
                }
            }
    
            /// <remarks/>
            public byte Current
            {
                get
                {
                    return this.currentField;
                }
                set
                {
                    this.currentField = value;
                }
            }
        }
    
    }
    

当您的生产 xml 中有命名空间时,当您在 cmets 中进行更新时,您可以使用在我的另一个示例中稍作修改的相同方法:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace ConsoleApplication11
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<env:Envelope xmlns:env=""w3.org/2003/05/soap-envelope"" xmlns:m0=""schemas/type.xsd"" xmlns:m1=""schemas/app.xsd"">
    <env:Body>
        <m1:GetLimitsRes > 
            <m1:Response Response=""1""> 
                <m0:Limits> 
                    <m0:Row> 
                        <m0:LimitId>100</m0:LimitId> 
                        <m0:Max>10000</m0:Max> 
                        <m0:Current>0</m0:Current> 
                    </m0:Row> 
                    <m0:Row> 
                        <m0:LimitId>101</m0:LimitId> 
                        <m0:Max>10000</m0:Max> 
                        <m0:Current>0</m0:Current> 
                    </m0:Row> 
                </m0:Limits> 
            </m1:Response>
        </m1:GetLimitsRes>
    </env:Body> 
</env:Envelope>";

            XmlSerializer d = new XmlSerializer(typeof(Envelope));
            Envelope e = (Envelope)d.Deserialize(new StringReader(xml));

            Console.WriteLine("Iterating all limits:");
            foreach (var lim in e.Body.GetLimitsRes.Response.Limits)
            {
                Console.WriteLine($"LimitId: {lim.LimitId}, Current: {lim.Current}, Max: {lim.Max}");
            }

            Console.WriteLine();
            LimitsRow particularLimit = e.Body.GetLimitsRes.Response.Limits.FirstOrDefault(l => l.LimitId == 101);
            if (particularLimit != null)
            {
                Console.WriteLine($"Particular limit: {particularLimit.LimitId}, Current: {particularLimit.Current}, Max: {particularLimit.Max}");
            }

            Console.WriteLine("Press any key to finish...");
            Console.ReadKey();
        }
    }


    /// <remarks/>
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "w3.org/2003/05/soap-envelope")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "w3.org/2003/05/soap-envelope", IsNullable = false)]
    public partial class Envelope
    {

        private EnvelopeBody bodyField;

        /// <remarks/>
        public EnvelopeBody Body
        {
            get
            {
                return this.bodyField;
            }
            set
            {
                this.bodyField = value;
            }
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "w3.org/2003/05/soap-envelope")]
    public partial class EnvelopeBody
    {

        private GetLimitsRes getLimitsResField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Namespace = "schemas/app.xsd")]
        public GetLimitsRes GetLimitsRes
        {
            get
            {
                return this.getLimitsResField;
            }
            set
            {
                this.getLimitsResField = value;
            }
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "schemas/app.xsd")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "schemas/app.xsd", IsNullable = false)]
    public partial class GetLimitsRes
    {

        private GetLimitsResResponse responseField;

        /// <remarks/>
        public GetLimitsResResponse Response
        {
            get
            {
                return this.responseField;
            }
            set
            {
                this.responseField = value;
            }
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "schemas/app.xsd")]
    public partial class GetLimitsResResponse
    {

        private LimitsRow[] limitsField;

        private byte responseField;

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayAttribute(Namespace = "schemas/type.xsd")]
        [System.Xml.Serialization.XmlArrayItemAttribute("Row", IsNullable = false)]
        public LimitsRow[] Limits
        {
            get
            {
                return this.limitsField;
            }
            set
            {
                this.limitsField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public byte Response
        {
            get
            {
                return this.responseField;
            }
            set
            {
                this.responseField = value;
            }
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "schemas/type.xsd")]
    public partial class LimitsRow
    {

        private byte limitIdField;

        private ushort maxField;

        private byte currentField;

        /// <remarks/>
        public byte LimitId
        {
            get
            {
                return this.limitIdField;
            }
            set
            {
                this.limitIdField = value;
            }
        }

        /// <remarks/>
        public ushort Max
        {
            get
            {
                return this.maxField;
            }
            set
            {
                this.maxField = value;
            }
        }

        /// <remarks/>
        public byte Current
        {
            get
            {
                return this.currentField;
            }
            set
            {
                this.currentField = value;
            }
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "schemas/type.xsd")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "schemas/type.xsd", IsNullable = false)]
    public partial class Limits
    {

        private LimitsRow[] rowField;

        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("Row")]
        public LimitsRow[] Row
        {
            get
            {
                return this.rowField;
            }
            set
            {
                this.rowField = value;
            }
        }
    }
}

【讨论】:

  • 谢谢米哈尔。很高兴你能理解,我想要什么。再次感谢,我们来我的国家(孟加拉国、达卡)共进晚餐(您的选择)。
  • Michal,您的代码可以用于没有命名空间的简单反序列化。如果我尝试使用 xml:ns,那就不行了。
  • 是的,Michal,我之前没有提到过。你能告诉我我是怎么做的吗?
  • "w3.org/2003/05/soap-envelope" xmlns:m0="schemas/type.xsd" xmlns: m1="schemas/app.xsd"> 100100000 env:Body> "
【解决方案2】:

试试 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);

            var results = doc.Descendants("Row").Select(x => new {
                limitId = (int)x.Element("LimitId"),
                max = (int)x.Element("Max"),
                current = (int)x.Element("Current")
            }).ToList();
        }
    }

}

【讨论】:

  • 您的回答是部分符合。但这很简单。谢谢。
  • 某些情况下手动解析xml然后反序列化更容易。我喜欢让人们选择使用哪种方法。
  • 谢谢jdweng。请解决它: "; 100 100000:Response> "
  • 文件中有分号需要去掉。您可以在 cs 菜单中检查 xml,执行以下操作:项目:添加新项目:Xml 文件。然后将xml粘贴到视图中。错误将像任何其他编译器错误一样显示在“错误列表”中。
  • 是的,我已经遇到过,需要更换方法来解决问题。
猜你喜欢
  • 1970-01-01
  • 2020-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-03
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
相关资源
最近更新 更多