【问题标题】:Reading a child node value from a big xml in C#从 C# 中的大 xml 读取子节点值
【发布时间】:2020-09-12 06:03:37
【问题描述】:

我有来自服务的 4000 行 xmlresponse。我使用所需的标签名称从那个大 xml 中提取了特定部分

XmlNodeList xmlForms = xmlDoc.GetElementsByTagName("Form");

从此节点示例部分 xml 如下所示

 <Form>
  <FormID>3434294</FormID>
  <StatusDate>0001-01-01T00:00:00</StatusDate>
  <InternalFormNo>CADFADSFSAGDSADG01</InternalFormNo>
  <ExternalFormNo>CADFASDFASFSC1001</ExternalFormNo>
  <ProposalDescription>Treatment</ProposalDescription>
  <ProposalForm>false</ProposalForm>
  <StateApprovals>
    <StateApproval>
      <StateApprovalID>2245363363636</StateApprovalID>
      <IssueLimitSet>
        <IssueLimitSetID>88</IssueLimitSetID>
        <Name>AccAdv</Name>
        <Note />
        <ModifyDate>0001-01-01T00:00:00</ModifyDate>
        <IssueLimits>
          <IssueLimit>
            <IssueLimtID>80</IssueLimtID>
            <GIAmount>62</GIAmount>
            <SIAmount>0.00</SIAmount>
            <ChangeProcessingCGIAmount>0</ChangeProcessingCGIAmount>
            <MaximumMultiSelect>0</MaximumMultiSelect>
            <CreateDate>0001-01-01T00:00:00</CreateDate>
            <ModifyDate>0001-01-01T00:00:00</ModifyDate>
          </IssueLimit>
        </IssueLimits>
      </IssueLimitSet>
      <SpecialProcessing>false</SpecialProcessing>
      <ModifyUser>TESTUSER</ModifyUser>
      <ModifyDate>2016-02-17T17:52:59.163</ModifyDate>
    </StateApproval>
  </StateApprovals>
</Form>

我需要读取节点 GIAmount 并提取它的值 (62)。但是 xpath 表示法总是给我空值。如何从此子 xml 中读取此子节点。简单的 xpath 也总是给出 null 。

foreach (XmlNode form in xmlForms)
                        {
                            var statusDate= form.SelectSingleNode("/Form/StatusDate"); //This always null i am getting

}

----------------原始xml------------在Variations->Forms->Form下 --在某些情况下,出现多个表单标签,我需要读取每个表单中的特定节点-------

<?xml version="1.0" encoding="utf-8"?>
<Product xmlns="http://testtest.com/twmku">
  <ProductID>72</ProductID>
  <InternalDescription>AccidentAdvance</InternalDescription>
  <ExternalDescription>AccidentAdvance</ExternalDescription>
  <Variations>
    <Variation>
      <VariationID>231</VariationID>
      <InternalDescription>AccidentAdvance123</InternalDescription>
      <ExternalDescription>AccidentAdvance</ExternalDescription>
      <ProposalDescription />
      <IsProposalReady>false</IsProposalReady>      
      <StatusDate>2009-03-26T00:00:00</StatusDate>
      <EffectiveDate>2009-04-01T00:00:00</EffectiveDate>
      <WithdrawnDate>0001-01-01T00:00:00</WithdrawnDate>
      <ModifyUser>Utesruser</ModifyUser>
      <ModifyDate>2011-11-30T10:35:26.313</ModifyDate>
      <Employers />
      <Forms>
        <Form>
          <FormID>3493</FormID>        
          <IsGeneric>true</IsGeneric>
          <HasLimitsInUnits>true</HasLimitsInUnits>
          <Description>AccAdv Master Policy</Description>
          <CreateUser>US\testMW</CreateUser>
          <CreateDate>0001-01-01T00:00:00</CreateDate>
          <ModifyUser>US\testMW</ModifyUser>
          <ModifyDate>2011-12-12T11:42:40.06</ModifyDate>          
          <DataElements />
          <StateApprovals>
            <StateApproval>
              <StateApprovalID>2256556</StateApprovalID> 
              <IssueLimitSet>
                <IssueLimitSetID>88</IssueLimitSetID>
                <Name>AccAdv Modtest</Name>
                <Note />
                <ModifyDate>0001-01-01T00:00:00</ModifyDate>
                <IssueLimits>
                  <IssueLimit>
                    <IssueLimtID>80</IssueLimtID>
                    <Keyword>AccAdv Mod 1</Keyword>
                    <MinMarketingLimit>0.50</MinMarketingLimit>
                    <MaxMarketingLimit>12.00</MaxMarketingLimit>
                    <CGIAmount>0.00</CGIAmount>
                    <GIAmount>6</GIAmount>
                    <SIAmount>0.00</SIAmount>
                    <ChangeProcessingCGIAmount>0</ChangeProcessingCGIAmount>                   
                    <CreateDate>0001-01-01T00:00:00</CreateDate>
                    <ModifyDate>0001-01-01T00:00:00</ModifyDate>
                  </IssueLimit>
                </IssueLimits>
              </IssueLimitSet>
              <StateRequirementSet />
              <QuestionSet />
              <SICSet />
              <DateFiled>0001-01-01T00:00:00</DateFiled>          
              <SpecialProcessing>false</SpecialProcessing>
              <ModifyUser>JBtestD</ModifyUser>
              <ModifyDate>2016-02-18T14:39:50.927</ModifyDate>
            </StateApproval>
          </StateApprovals>
          <Parameters />
          <IsSelected>true</IsSelected>
        </Form>

        <Form>
          <FormID>3495</FormID>
          <IsGeneric>true</IsGeneric>
          <HasLimitsInUnits>true</HasLimitsInUnits>
          <Description>AccAdv Master main</Description>
          <CreateUser>US\testMqW</CreateUser>
          <CreateDate>0001-01-01T00:00:00</CreateDate>
          <ModifyUser>US\testMW</ModifyUser>
          <ModifyDate>2011-12-12T11:42:40.06</ModifyDate>
          <DataElements />
          <StateApprovals>
            <StateApproval>
              <StateApprovalID>26556</StateApprovalID>
              <IssueLimitSet>
                <IssueLimitSetID>88</IssueLimitSetID>
                <Name>AccAdv Moretest</Name>
                <Note />
                <ModifyDate>0001-01-01T00:00:00</ModifyDate>
                <IssueLimits>
                  <IssueLimit>
                    <IssueLimtID>84</IssueLimtID>
                    <Keyword>AccAdv Mod 1</Keyword>
                    <MinMarketingLimit>0.50</MinMarketingLimit>
                    <MaxMarketingLimit>12.00</MaxMarketingLimit>
                    <CGIAmount>0.00</CGIAmount>
                    <GIAmount>34</GIAmount>
                    <SIAmount>0.00</SIAmount>
                    <ChangeProcessingCGIAmount>0</ChangeProcessingCGIAmount>
                    <CreateDate>0001-01-01T00:00:00</CreateDate>
                    <ModifyDate>0001-01-01T00:00:00</ModifyDate>
                  </IssueLimit>
                </IssueLimits>
              </IssueLimitSet>
              <StateRequirementSet />
              <QuestionSet />
              <SICSet />
              <DateFiled>0001-01-01T00:00:00</DateFiled>
              <SpecialProcessing>false</SpecialProcessing>
              <ModifyUser>JBtestD</ModifyUser>
              <ModifyDate>2016-02-18T14:39:50.927</ModifyDate>
            </StateApproval>
          </StateApprovals>
          <Parameters />
          <IsSelected>true</IsSelected>
        </Form>
      </Forms>      
      <ParameterValueSets />
      <AllowCustomRates>false</AllowCustomRates>
    </Variation>
  </Variations>
</Product>

【问题讨论】:

    标签: c# xml xpath


    【解决方案1】:

    您已经以Form 元素为目标,因此没有理由将它包含在XPath 中。只需跳过该标记,并使用其后代组成路径。

    在你的情况下:"StateApprovals/StateApproval/IssueLimitSet/IssueLimits/GIAmount"

    或者,更简洁:"//GIAmount"

    请注意,我的回答是基于您帖子的片段,路径可能会根据实际内容发生变化。

    【讨论】:

    • 我尝试了所有选项仍然为空。当我观察到我的 xml 不必要的 xmlns 命名空间被随机添加时。我不确定为什么 xpath 表达式对我不起作用,在我读的一篇文章中,因为 xmlns xpath 不起作用,我们需要删除。但如果它在一个地方我们可以删除,甚至尝试使用正则表达式删除仍然总是给出 null。
    【解决方案2】:

    最好使用LINQ to XML。使用它的方法,很容易获得任何 XML 元素。

    (1) 您的 XML 具有默认命名空间。需要考虑到这一点。 (2) 多个&lt;Form&gt;...&lt;/Form&gt; 元素需要一个循环。

    c#

    void Main()
    {
        XElement xelem = XElement.Parse(@"<Product xmlns='http://testtest.com/twmku'>
      <ProductID>72</ProductID>
      <InternalDescription>AccidentAdvance</InternalDescription>
      <ExternalDescription>AccidentAdvance</ExternalDescription>
      <Variations>
        <Variation>
          <VariationID>231</VariationID>
          <InternalDescription>AccidentAdvance123</InternalDescription>
          <ExternalDescription>AccidentAdvance</ExternalDescription>
          <ProposalDescription />
          <IsProposalReady>false</IsProposalReady>      
          <StatusDate>2009-03-26T00:00:00</StatusDate>
          <EffectiveDate>2009-04-01T00:00:00</EffectiveDate>
          <WithdrawnDate>0001-01-01T00:00:00</WithdrawnDate>
          <ModifyUser>Utesruser</ModifyUser>
          <ModifyDate>2011-11-30T10:35:26.313</ModifyDate>
          <Employers />
          <Forms>
            <Form>
              <FormID>3493</FormID>        
              <IsGeneric>true</IsGeneric>
              <HasLimitsInUnits>true</HasLimitsInUnits>
              <Description>AccAdv Master Policy</Description>
              <CreateUser>US\testMW</CreateUser>
              <CreateDate>0001-01-01T00:00:00</CreateDate>
              <ModifyUser>US\testMW</ModifyUser>
              <ModifyDate>2011-12-12T11:42:40.06</ModifyDate>          
              <DataElements />
              <StateApprovals>
                <StateApproval>
                  <StateApprovalID>2256556</StateApprovalID> 
                  <IssueLimitSet>
                    <IssueLimitSetID>88</IssueLimitSetID>
                    <Name>AccAdv Modtest</Name>
                    <Note />
                    <ModifyDate>0001-01-01T00:00:00</ModifyDate>
                    <IssueLimits>
                      <IssueLimit>
                        <IssueLimtID>80</IssueLimtID>
                        <Keyword>AccAdv Mod 1</Keyword>
                        <MinMarketingLimit>0.50</MinMarketingLimit>
                        <MaxMarketingLimit>12.00</MaxMarketingLimit>
                        <CGIAmount>0.00</CGIAmount>
                        <GIAmount>6</GIAmount>
                        <SIAmount>0.00</SIAmount>
                        <ChangeProcessingCGIAmount>0</ChangeProcessingCGIAmount>                   
                        <CreateDate>0001-01-01T00:00:00</CreateDate>
                        <ModifyDate>0001-01-01T00:00:00</ModifyDate>
                      </IssueLimit>
                    </IssueLimits>
                  </IssueLimitSet>
                  <StateRequirementSet />
                  <QuestionSet />
                  <SICSet />
                  <DateFiled>0001-01-01T00:00:00</DateFiled>          
                  <SpecialProcessing>false</SpecialProcessing>
                  <ModifyUser>JBtestD</ModifyUser>
                  <ModifyDate>2016-02-18T14:39:50.927</ModifyDate>
                </StateApproval>
              </StateApprovals>
              <Parameters />
              <IsSelected>true</IsSelected>
            </Form>
            <Form>
              <FormID>3495</FormID>
              <IsGeneric>true</IsGeneric>
              <HasLimitsInUnits>true</HasLimitsInUnits>
              <Description>AccAdv Master main</Description>
              <CreateUser>US\testMqW</CreateUser>
              <CreateDate>0001-01-01T00:00:00</CreateDate>
              <ModifyUser>US\testMW</ModifyUser>
              <ModifyDate>2011-12-12T11:42:40.06</ModifyDate>
              <DataElements />
              <StateApprovals>
                <StateApproval>
                  <StateApprovalID>26556</StateApprovalID>
                  <IssueLimitSet>
                    <IssueLimitSetID>88</IssueLimitSetID>
                    <Name>AccAdv Moretest</Name>
                    <Note />
                    <ModifyDate>0001-01-01T00:00:00</ModifyDate>
                    <IssueLimits>
                      <IssueLimit>
                        <IssueLimtID>84</IssueLimtID>
                        <Keyword>AccAdv Mod 1</Keyword>
                        <MinMarketingLimit>0.50</MinMarketingLimit>
                        <MaxMarketingLimit>12.00</MaxMarketingLimit>
                        <CGIAmount>0.00</CGIAmount>
                        <GIAmount>34</GIAmount>
                        <SIAmount>0.00</SIAmount>
                        <ChangeProcessingCGIAmount>0</ChangeProcessingCGIAmount>
                        <CreateDate>0001-01-01T00:00:00</CreateDate>
                        <ModifyDate>0001-01-01T00:00:00</ModifyDate>
                      </IssueLimit>
                    </IssueLimits>
                  </IssueLimitSet>
                  <StateRequirementSet />
                  <QuestionSet />
                  <SICSet />
                  <DateFiled>0001-01-01T00:00:00</DateFiled>
                  <SpecialProcessing>false</SpecialProcessing>
                  <ModifyUser>JBtestD</ModifyUser>
                  <ModifyDate>2016-02-18T14:39:50.927</ModifyDate>
                </StateApproval>
              </StateApprovals>
              <Parameters />
              <IsSelected>true</IsSelected>
            </Form>
          </Forms>      
          <ParameterValueSets />
          <AllowCustomRates>false</AllowCustomRates>
        </Variation>
      </Variations>
    </Product>");
    
        //string GIAmount = GIAmount.Descendants(ns + "GIAmount").FirstOrDefault().Value;
        XNamespace ns = xelem.GetDefaultNamespace();
    
        foreach (var el in xelem.Descendants(ns + "GIAmount"))
        {
            Console.WriteLine("GIAmount={0}", el.Value);    
        }
    }
    

    输出

    GIAmount=6
    GIAmount=34
    

    【讨论】:

    • 感谢您的回复。您在独立应用程序中工作的示例。当我尝试合并到实际应用程序中时,我得到了 System.Xml.XmlException 异常:'根级别的数据无效。第 1 行,位置 1。当我检查我的表单变量时,添加了不必要的命名空间,但原来它不存在。比如 这些 xmlns 标签被添加了。
    • @San,请用现实生活中的 XML、命名空间等更新您的原始帖子。我会相应地更新我的答案。
    • 我已经更新了 xml,你现在可以检查一下。在原始响应中,我将只有一个 xmlns 标记,每个 xml 文档都将具有该标记。一旦我执行 XmlNodeList xmlForms = xmlDoc.GetElementsByTagName("Form");我得到的所有表单标签。如果我尝试编写 xpath 表达式,则它不起作用。它总是返回 null。将其解析为 xelemt 它给出了上述异常
    • 我只在解析时遇到问题。在遍历每个表单时,我试图解析表单内容,以便提取所需的值。 XmlNodeList xmlForms = xmlDoc.GetElementsByTagName("Form"); foreach (xmlForms 中的 XmlNode 表单) { XElement ele = XElement.Parse(form.ToString()); }
    • @San,我的回答中缺少什么?我展示了如何检索所有 GIAmount 值。
    【解决方案3】:

    一个值通常是不够的信息。试试下面的 xml linq:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    using System.IO;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                string xml = File.ReadAllText(FILENAME);
                XDocument doc = XDocument.Parse(xml);
                XNamespace ns = doc.Root.GetDefaultNamespace();
    
                List<StateApproval> approvals = doc.Descendants(ns + "StateApproval").Select(x => new StateApproval()
                {
                    id = (string)x.Element(ns + "StateApprovalID"),
                    limitSetId = (string)x.Descendants(ns + "IssueLimitSetID").FirstOrDefault(),
                    name = (string)x.Descendants(ns + "Name").FirstOrDefault(),
                    modifyDate = (DateTime)x.Descendants(ns + "ModifyDate").FirstOrDefault(),
                    issueLimitId = (string)x.Descendants(ns + "IssueLimtID").FirstOrDefault(),
                    giAmount = (decimal)x.Descendants(ns + "GIAmount").FirstOrDefault(),
                    siAmount = (decimal)x.Descendants(ns + "SIAmount").FirstOrDefault(),
                    changeAmount = (decimal)x.Descendants(ns + "ChangeProcessingCGIAmount").FirstOrDefault(),
                    min = (decimal)x.Descendants(ns + "MinMarketingLimit").FirstOrDefault(),
                    max = (decimal)x.Descendants(ns + "MaxMarketingLimit").FirstOrDefault(),
                    createDate = (DateTime)x.Descendants(ns + "CreateDate").FirstOrDefault(),
                }).ToList();
            }
        }
        public class StateApproval
        {
            public string id { get; set; }
            public string limitSetId { get; set; }
            public string name { get; set; }
            public DateTime modifyDate { get; set; }
            public string issueLimitId { get; set; }
            public decimal giAmount { get; set; }
            public decimal siAmount { get; set; }
            public decimal changeAmount { get; set; }
            public decimal min { get; set; }
            public decimal max { get; set; }
            public DateTime createDate { get; set; }
    
        }
    }
    

    【讨论】:

    • 我没有提供加载功能的 uri 路径。我的 xml 的运行时子集存在。它也没有转换为字符串。无法尝试您的选项。
    • 用于字符串:XDocument doc = XDocument.Parse(string);
    • 是的,我试过了。这。但对我来说,在解析 xmlexception 根级别的数据时异常给出 line1 位置 1 无效。当我观察到我的 xml 获得不必要的命名空间时。为此,我无法继续进行。 :(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    相关资源
    最近更新 更多