如何从没有 xml 标签的 xml 字符串中获取数据-C#

Posted

技术标签:

【中文标题】如何从没有 xml 标签的 xml 字符串中获取数据-C#【英文标题】:How to fetch data from a xml string without a xml tag- C# 【发布时间】:2017-07-16 04:10:01 【问题描述】:

我有一个像下面这样的课程

namespace CustomerData
  
   [Serializable]
  public class Customer
     
    [JsonProperty(PropertyName = "u_additional_DeskNumber ")]
    public string DeskNumber  get; set; 
    [JsonProperty(PropertyName = "u_additional_customerid")]
     public string CustomerID get; set; 
   
  

我正在从数据库中获取数据并映射到这个客户类。从数据库 DeskNumber 将以下列格式返回。desknumber 的 Db 数据类型是 nvarchar

格式 1。

   <AdditionalInfo><Number>164</Number></AdditionalInfo>

格式2

 <AdditionalInfo><Code>GLW51</Code><LangCode>GLW51</LangCode><TzCode>GLW51</TzCode></AdditionalInfo>

如果数据返回格式1,我需要返回数字标签下的值(即.164)。数字标签下的值在不同的时间会有所不同。如果从databse返回的值是格式1以外的任何其他格式,则值应设置为空白。

我正在使用以下通用方法将数据读取器映射到相应的类

     private static List<T> MapDataToEntity<T>(IDataReader dr) where T : new()
    
        Type businessEntityType = typeof(T);
        List<T> entitys = new List<T>();
        Hashtable hashtable = new Hashtable();
        PropertyInfo[] properties = businessEntityType.GetProperties();

        foreach (PropertyInfo info in properties)
        
            hashtable[info.Name.ToUpper()] = info;
        

        while (dr.Read())
        
            T newObject = new T();
            for (int index = 0; index < dr.FieldCount; index++)
            
                PropertyInfo info = (PropertyInfo)
                                    hashtable[dr.GetName(index).ToUpper()];
                if ((info != null) && info.CanWrite)
                
                    info.SetValue(newObject, dr.GetValue(index), null);
                
            
            entitys.Add(newObject);
        

        dr.Close();
        return entitys;
    

所以我有以下问题,

1.如何从下面的字符串中找到数字标签下的值

 <AdditionalInfo><Number>164</Number></AdditionalInfo>

2。如何添加一个逻辑,如果它不是上述格式(即Format1),那么它应该是空白的。

3.我需要把这个逻辑放在哪里,在DeskNumber的Set Method中??

任何人都可以通过示例代码提出更好的方法

【问题讨论】:

您的第二段 XML 无效,并且这两条 XML 似乎都与您提供的示例类中的属性无关。然后,您展示了似乎根本不使用 XML 的代码。所有这些都使这个问题很难理解。请阅读codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question 并编辑问题以使其更清楚很多。我还强烈建议使用 Dictionary&lt;&gt; 而不是 Hashtable - 尽可能避免使用非泛型集合。 vmb,您不清楚是否需要写入 DeskNumber(除来自 dataReader 之外)。然后应该生成 XML 吗? @Jon Skeet 。属性名称和 xml 之间没有关系。从 db 它将返回以 AdditionalInfo 开头的这个 xml 字符串。所以我只想从这个 xml 字符串中找出 DeskNumber 并需要分配这个DeskNumber 的属性。 如果您只对“从某些 XML 中提取特定元素”感兴趣,那么与数据库相关的所有代码,甚至您要设置的属性,都无关紧要。有很多关于解析 XML、查找特定元素(如果存在)和查找其值的问题。 【参考方案1】:

您可以使用以下代码获取格式 1 等 xml 字符串的值:

var xdoc = System.Xml.Linq.XDocument.Parse(xml_string);
var xelement = xdoc.Elements("AdditionalInfo").SelectMany(x => x.Elements("Number")).FirstOrDefault();
string res = (xelement != null) ? xelement.Value : "";

如果xml_string 的格式不正确(格式1),此代码将返回一个空白字符串。如果你有一些未知的格式,你可以使用 try/catch 块。

要使用此代码,您有一些选择。一种是在DeskNumber 属性的设置器中使用它。我建议定义另一个属性,如 DeskNumberXml 并用 JsonProperty 属性装饰它:

string _deskNumberXml;
[JsonProperty(PropertyName = "u_additional_DeskNumber ")]
public string DeskNumberXml 
 
   get  return _deskNumberXml; 
   set
   
      _deskNumberXml = value;
      try
      
         var xdoc = System.Xml.Linq.XDocument.Parse(value);
         var xelement = xdoc.Elements("AdditionalInfo").SelectMany(x => x.Elements("Number")).FirstOrDefault();
         DeskNumber = (xelement != null) ? xelement.Value : "";
      
      catch
      
         DeskNumber = "";
      
   


public string DeskNumber  get; set; 

【讨论】:

感谢您的快速响应。我们使用新属性的原因是什么..我可以使用它 DeskNumber 设置方法本身..对吗??..我创建了一个通用映射逻辑来映射任何内容从 db 返回到类中的属性名称。在 db 中,数据字段将返回与属性名称相同的名称。 XDocument 尤其是 SelectMany 有点矫枉过正。您可以将 xml 解析为 XElement 并使用 e.Element("Number")?.Value ?? "" @vmb 是的,您不需要定义新属性。您可以在映射类中使用我的第一个代码块。检查属性名称是否为DeskNumber 然后应用我的代码。

以上是关于如何从没有 xml 标签的 xml 字符串中获取数据-C#的主要内容,如果未能解决你的问题,请参考以下文章

如何使用powershell从xml中获取属性值?

当标签的url部分时如何提取Oracle XML

如何将xml传递给C#中的View?

如何使用 php 获取 XML 中所有现有标签的列表

如何在python中根据xml标签获取文本?

如何获取 XML 中特定标签的列表