【问题标题】:How can i fetch the 'Value' from the keyvalue pair using c#如何使用 c# 从键值对中获取“值”
【发布时间】:2017-06-22 01:10:20
【问题描述】:

我想使用 c# 获取“名称”下可用的各种参数的“值”中提到的字符串。 这是我当前的xml如下:

<DrWatson>
  <Sets>
    <Set>
      <APIParameters>
        <Parameter Name="SID_STAGE" Value="101198" Required="true" />
        <Parameter Name="SID_QE" Value="Test 91817" Required="true" />
      </APIParameters>
    </Set>
  </Sets>
</DrWatson>

我想为Name = SID_STAGE 获取'Value' 下的'101198'。 请建议我如何执行它。

【问题讨论】:

  • 用 linq 解析 xml stackoverflow.com/questions/670563/linq-to-read-xml 真的很难找到
  • 请下次提供一些您已经拥有的代码并描述您遇到的问题
  • 这是一个完全正确的问题。我认为不需要提供任何代码,任何对 C# .NET 相对较新的人都不会真正知道要使用哪些类。我看不出用户应该被否决的任何充分理由,特别是考虑到他们显然是新用户。在第一组问题上被如此严厉地否决是非常令人反感的。

标签: c# xml key-value


【解决方案1】:

您可以使用 LINQ to XML 解析参数字典(这是存储键值对的自然方式):

var xdoc = XDocument.Load(path_to_xml);
var parameters = xdoc.Descendants("Parameter")
                     .ToDictionary(p => (string)p.Attribute("Name"),
                                   p => (string)p.Attribute("Value"));

var stage = parameters["SID_STAGE"];

请记住,您应该在获取参数之前检查参数是否存在于字典中(如果参数可能不在您的 xml 中):

if (parameters.ContainsKey("SID_STAGE"))
    // get parameter value

还可以使用 XPath 使查询更加具体(如果某处可能是另一个 Parameter 元素):

var xpath = "DrWatson/Sets/Set/APIParameters/Parameter";
var parameters = xdoc.XPathSelectElements(xpath)
                     .ToDictionary(p => (string)p.Attribute("Name"),
                                   p => (string)p.Attribute("Value"));

【讨论】:

  • Dictionary 的好方法,喜欢它。只是怕在属性 Name 不存在的情况下有点ArgumentNullException 异常
  • @IlyaIvanov 谢谢,我认为参数名称是必需的(否则没有意义),但使用Where(p =&gt; (string)p.Attribute("Name") != null) 过滤器很容易解决:)
  • 是的,当然。只是想提一下。当我在项目上使用ToDictionary 时,我有一些负面的经验,哪个键可能为空。这在当时还不是很明显)
【解决方案2】:
var result = XElement.Parse(xmlString)
                     .Descendants("Parameter")
                     .First(node => (string)node.Attribute("Name") == "SID_STAGE")
                     .Attribute("Value");

Console.WriteLine(result.Value); //prints 101198

不存在此属性的元素会抛出异常。如果您想要其他行为,请考虑使用FirstOrDefault

【讨论】:

  • 对于这个示例 xml,它可以工作,但是如果有另一个元素的属性 Name 等于 SID_STAGE 怎么办? :)
  • @lazyberezovsky 通过添加 Parameter 节点名称来修复。请注意,XML 允许有多个具有相同 Name 属性的 Parameter 节点;)这将导致我们的两个解决方案出现问题,我的解决方案不会抛出异常,这有时会很糟糕
  • 再写几行,我们会处理的 :) GroupBy(p =&gt; (string)p.Attribute("Name")).Where(g =&gt; g.Key != null).Select(g =&gt; g.First()).ToDictionary(...)
【解决方案3】:

使用LINQ to XML 查询:

var xml = XDocument.Load("path...");
var foo = (from n in xml.Descendants("APIParameters")
           where n.Element("Parameter").Attribute("Name").Value == "SID_STAGE"
           select n.Element("Parameter").Attribute("Value").Value).FirstOrDefault();

给予:

101198

【讨论】:

  • 我遇到了一个异常。
  • 抛出了什么异常,在哪一行?我已经对此进行了测试,对我来说效果很好
  • 得到以下信息:调用目标抛出异常。
  • 我只在第 1 行得到这个
  • 这是var xml = XDocument.Load("path..."); - 尽量不要只是盲目地复制和粘贴代码。需要设置XDocument.Load()的文件路径参数。该方法采用您的 XML 或 XML 字符串本身的路径。由于我不知道您的 XML 的路径,因此我将其替换为 path... 纯粹作为示例
【解决方案4】:
using System;
using System.Xml.Linq;
using System.Web;
namespace YourProjectName
{
    public static class XmlFileRetrieve
    {
        public static string GetParameterValue(string name)
        {
            try
            {
                string path = HttpContext.Current.Server.MapPath("~/YourFolderName/YourXmlFileName.xml");
                XDocument doc = XDocument.Load(path);
                if (!(doc == null))
                {
                    var parameter = (from el in doc.Root.Elements("Parameter")
                                where (string)el.Attribute("Name") == name
                                select (string)el.Attribute("value")).Select(keyvalue => new { name = keyvalue }).Single(); ;
                    return parameter.name;
                }
                return "";
            }
            catch (Exception e)
            {string error=e.Message;return "";
            }
        }
    }
}

【讨论】:

  • 应该得到值;提供名称为 SID_STAGE
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-16
  • 2019-11-28
  • 2020-08-29
  • 1970-01-01
相关资源
最近更新 更多