【问题标题】:Can't Retrieve Values of XML Elements using XElement无法使用 XElement 检索 XML 元素的值
【发布时间】:2013-07-13 07:01:30
【问题描述】:

我正在尝试从通过文件浏览器提供的 XML 文件中读取,但即使我可以看到 xml 文件通过元素,值也始终为空。

  public void UploadXml(Stream fileStream)
  {
    //Load xml
      fileStream.Position = 0;

      var xdoc = XElement.Load(fileStream);

      IEnumerable<XElement> elements = xdoc.Elements();

      var codeList = new CodeList();

      foreach (var item in elements)
      {
          codeList.Name = item.Element("CODELIST_NAME").Value;
          codeList.Description = item.Element("DESRIPTION").Value;
          codeList.Version = item.Element("VERSION").Value;
          codeList.EffectiveDate = DateTime.Parse(item.Element("EFFECTIVE_DATE").Value);
          codeList.ExpirationDate = DateTime.Parse(item.Element("EXPIRATION_DATE").Value);
      }
      // save code list

      // get code list ID

      // create codes
  }

更新 XML

<?xml version="1.0" encoding="utf-8"?>
<CONTEXT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns:xsd="http://www.w3.org/2001/XMLSchema"    
         xmlns="http://www.w3.org/2000/xmlns">
  <CONTEXT_NAME></CONTEXT_NAME>
  <CODELIST>
    <CODELIST_NAME></CODELIST_NAME>
        <DESRIPTION></DESRIPTION>
        <VERSION></VERSION>
        <USERNAME>test user</USERNAME>
        <OWNER_TEAM />
        <STEWARD_TEAM />
        <STATUS></STATUS>
        <LAST_MODIFIED></LAST_MODIFIED>
        <LAST_MODIFIED_NAME></LAST_MODIFIED_NAME>
        <EFFECTIVE_DATE></EFFECTIVE_DATE>
        <EXPIRATION_DATE></EXPIRATION_DATE>
        <FILE_TIMESTAMP></FILE_TIMESTAMP>
       <CONSTRAINED_VALUE>
           <CODE></CODE>
           <PARENT_ID />
           <NAME></NAME>
           <DESCRIPTION></DESCRIPTION>
       </CONSTRAINED_VALUE>
 </CODELIST>
</CONTEXT>

在一个普通文件中,显然文件中会有数据,我只需要为示例删除它。

受约束的值标签将针对数据库中的行重复

【问题讨论】:

  • 你能展示一个 XML 的例子吗?
  • 您能粘贴一个 XML 样本吗?另请注意,.Elements() 获取 1 级的直接后代元素,而不是低于它的所有级别。使用Descendents().Where(x =&gt; x is XElement) 让他们从整棵树上下来。
  • 我强烈怀疑这是一个命名空间问题。另请注意,如果日期/时间值符合 XML,只需将元素转换为 DateTime。
  • 此行代码抛出空异常错误 codeList.Name = item.Element("CODELIST_NAME").Value;在日期时间之前

标签: c# xml-parsing linq-to-xml xelement


【解决方案1】:

IEnumerable<XElement> elements = xdoc.Elements();

定义要解析的元素的父元素。例如,如果您的 xml 是这样的:

<parent>
    <CODELIST_NAME></CODELIST_NAME>
    <DESRIPTION></DESRIPTION>
    <VERSION></VERSION>
    <EFFECTIVE_DATE></EFFECTIVE_DATE>
    <EXPIRATION_DATE></EXPIRATION_DATE>
</parent>

然后写成

IEnumerable<XElement> elements = xdoc.Elements("parent");

詹尼斯

【讨论】:

  • 我已经尝试过这样的事情,但是当我这样做时,当我进行调试时,这些元素会“产生任何结果”
【解决方案2】:

您需要指定(默认)命名空间。

  var xdoc = XElement.Load(fileStream);
  var dns = xdoc.GetDefaultNamespace();
  ....

然后你的循环就变成了(也添加了一些范围更正)

  foreach (var item in elements)
  {
      var codeList = new CodeList();

      codeList.Name = item.Element(dns + "CODELIST_NAME").Value;
      codeList.Description = item.Element(dns + "DESRIPTION").Value;
      codeList.Version = item.Element(dns + "VERSION").Value;
      codeList.EffectiveDate = DateTime.Parse(item.Element(dns + "EFFECTIVE_DATE").Value);
      codeList.ExpirationDate = DateTime.Parse(item.Element(dns + "EXPIRATION_DATE").Value);

      // save code list
  }

【讨论】:

    【解决方案3】:

    感谢您的帮助,解决这个问题对我很有用

    我的问题在于我是如何读取这些值的。

    xdoc.Element(XName.Get("CODELIST", dns.NamespaceName)).Element(XName.Get("CODELIST_NAME", dns.NamespaceName)).Value,
    

    以这种方式阅读它已经为我解决了问题。

    【讨论】:

    • 是的,另一种方式更容易阅读,但由于某种原因它不适合我。
    【解决方案4】:

    我知道你找到了答案,但我想把我所做的让它正常运行只是为了好玩:) 这是我使用的代码:

    using System;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace xmlTesting
    {
      public class codeList
      {
        public string Name { get; set; }
        public string Description { get; set; }
        public string Version { get; set; }
        public DateTime EffectiveDate { get; set; }
        public DateTime ExpirationDate { get; set; }
      }
    
      class program {
    
        static void Main(string[] args)
        {
          var CL = UploadXml(XElement.Load(@"c:\debug\xmlcontent.xml"));
          Console.WriteLine(
            string.Format("name: {0}\nDesc: {1}\nVersion: {2}\nEffectivdate: {3}\nExp: {4}"
            , CL.Name, CL.Description, CL.Version, CL.EffectiveDate, CL.ExpirationDate)
            );
          Console.ReadKey(true);
        }
    
        public static codeList UploadXml(XElement xdoc)
        {
          var codeList = new codeList();
    
          foreach (XElement XE in xdoc.Descendants())
          {
            switch (XE.Name.LocalName)
            {
              case "CODELIST_NAME":
                codeList.Name = XE.Value;
                break;
              case "DESCRIPTION":
                if(codeList.Description == null)
                codeList.Description = XE.Value;
                break;
              case "VERSION":
                codeList.Version = XE.Value;
                break;
              case "EFFECTIVE_DATE":
                codeList.EffectiveDate = DateTime.Parse(XE.Value);
                break;
              case "EXPIRATION_DATE":
                codeList.ExpirationDate = DateTime.Parse( XE.Value);
                break;
            }
          }
          // save code list
    
          // get code list ID
    
          // create codes
          return codeList;
        }
      }
    }
    

    我使用的 xml 就是这个。

    <?xml version="1.0" encoding="utf-8"?>
    <CONTEXT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"    
             xmlns="http://www.w3.org/2000/xmlns">
      <CONTEXT_NAME></CONTEXT_NAME>
      <CODELIST>
        <CODELIST_NAME>a name</CODELIST_NAME>
            <DESCRIPTION>a desr</DESCRIPTION>
            <VERSION>test1.1</VERSION>
            <USERNAME>test user</USERNAME>
            <OWNER_TEAM />
            <STEWARD_TEAM />
            <STATUS></STATUS>
            <LAST_MODIFIED>a day</LAST_MODIFIED>
            <LAST_MODIFIED_NAME>trae</LAST_MODIFIED_NAME>
            <EFFECTIVE_DATE>07/05/1983</EFFECTIVE_DATE>
            <EXPIRATION_DATE>07/05/1983</EXPIRATION_DATE>
            <FILE_TIMESTAMP></FILE_TIMESTAMP>
           <CONSTRAINED_VALUE>
               <CODE></CODE>
               <PARENT_ID />
               <NAME></NAME>
               <DESCRIPTION></DESCRIPTION>
           </CONSTRAINED_VALUE>
     </CODELIST>
    </CONTEXT>
    

    【讨论】:

    • 这看起来很整洁,当我们在接下来的一两周内进行重构时,我将不得不尝试一下。我会及时通知你进展情况
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 2012-09-10
    • 1970-01-01
    • 2012-12-12
    相关资源
    最近更新 更多