【问题标题】:Obtain value stored within a set of attributes of a given type获取存储在给定类型的一组属性中的值
【发布时间】:2019-09-12 05:29:38
【问题描述】:

我有以下 XML 文件,我怎样才能获得存储在给定类型的标签中的值(在这种情况下说类型为“FileModel”) ..我怎样才能编写一些代码来获取值 Rep1 和 Rep2 。我需要这些值在方法中运行某个验证

我怎样才能做到这一点?

<?xml version="1.0"?>
<MainClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Items>
    <Settings xsi:type="FileModel">
      <Name>Rep1</Name>
      <IsActive>true</IsActive>
      <IsHidden>false</IsHidden>
    </Settings>
    <Settings xsi:type="FileModel">
      <Name>Rep2</Name>
      <IsActive>true</IsActive>
      <IsHidden>false</IsHidden>
    </Settings> 
   <Settings xsi:type="ServerModel">
      <Name>DelRep</Name>
      <IsActive>false</IsActive>
      <IsHidden>false</IsHidden>
    </Settings>
  </Items>
</MainClass>

【问题讨论】:

  • 您目前如何处理 XML?通过XmlSerializer反序列化?用 LINQ to XML 解析?用XmlDocument解析?
  • 现在我的整个 XML 文件存储为类似 string WholeContent = File.ReadAllText(this.FilePath); 的字符串,并且 WholeContent 在其他地方使用,但我认为 linq在这种情况下,将 XML 转换为更好的方法
  • 查看其他答案here,看看有什么可以帮助你的

标签: c# xml serialization


【解决方案1】:

您可以使用XPathXmlNamespaceManager 来做到这一点。

示例 (.NetFiddle):

using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

public class Program
{
    public static void Main()
    {
        var doc = XDocument.Parse(XmlString);
        var namespaceManager = new XmlNamespaceManager(new NameTable());
        namespaceManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
        var names = doc.XPathSelectElements(
            "/MainClass/Items/Settings[@xsi:type='FileModel']/Name",
            namespaceManager
        ).Select(e => e.Value);

        Console.WriteLine(String.Join(", ", names));
    }

    private static string XmlString = @"<?xml version=""1.0""?>
<MainClass xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
  <Items>
    <Settings xsi:type=""FileModel"">
      <Name>Rep1</Name>
      <IsActive>true</IsActive>
      <IsHidden>false</IsHidden>
    </Settings>
    <Settings xsi:type=""FileModel"">
      <Name>Rep2</Name>
      <IsActive>true</IsActive>
      <IsHidden>false</IsHidden>
    </Settings> 
   <Settings xsi:type=""ServerModel"">
      <Name>DelRep</Name>
      <IsActive>false</IsActive>
      <IsHidden>false</IsHidden>
    </Settings>
  </Items>
</MainClass>";
}

将输出:"Rep1, Rep2"

【讨论】:

    【解决方案2】:

    如果你想使用System.Xml:

    static void Main(string[] args)
        {
            List<string> result = new List<string>();
    
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("myfile.xml");
    
            XmlNodeList elemList = xmlDoc.GetElementsByTagName("Settings");
            foreach (XmlNode node in elemList)
            {
                if(node.Attributes["xsi:type"].Value == "FileModel")
                {
                    foreach (XmlNode item in node.ChildNodes)
                    {
                        if (item.Name == "Name")
                            result.Add(item.InnerText);
                    } 
                }
            }
        }
    

    【讨论】:

      【解决方案3】:

      您可以使用 linq to xml 来实现您想要的结果。它比你想象的要简单。您不需要完全了解 xml 或 linq。

      检索设置节点内的所有名称,类型等于FileModel

      代码:

      var doc = XDocument.Load("Path to xml file");
      //Or
      var doc = XDocument.Parse(XmlString);
      
      var ns = doc.Root.GetNamespaceOfPrefix("xsi");
      
      var names = doc.Descendants("Items")
          .Elements("Settings")
          .Where(x => x.Attribute(ns + "type").Value == "FileModel")
          .Select(x => x.Element("Name").Value)
          .ToList();
      
      
      names.ForEach(x => Console.WriteLine(x));
      

      输出:

      或者,如果您希望结果为单个字符串,则可以使用逗号(,) 加入上面的列表,例如,

      var allName = string.Join(", ", names);
      Console.WriteLine(allName);
      

      输出:

      Online Demo

      【讨论】:

        猜你喜欢
        • 2011-03-18
        • 2012-01-09
        • 1970-01-01
        • 1970-01-01
        • 2021-08-04
        • 1970-01-01
        • 2019-06-28
        相关资源
        最近更新 更多