简体   繁体   English

使用Xml.Xpath和Xml.Linq读取XML文件

[英]Read XML file using Xml.Xpath and Xml.Linq

I am trying to read the following XML file: 我正在尝试读取以下XML文件:

<?xml version="1.0" encoding="utf-8"?>
<Connection name="default">
  <Attribute name="server" value="localhost" />
  <Attribute name="database" value="mp" />
  <Attribute name="uid" value="root" />
  <Attribute name="password" value="m123" />
  <Attribute name="code" value="MK" />
</Connection>

With the following code: 使用以下代码:

        var doc = XDocument.Load("DBConnect.xml");
        var values = doc.XPathSelectElements("//Connection[@name='default']");
        foreach (var item in values)
        {
            foreach (var att in item.Elements("Attribute"))
            {
                _server = att.Attribute("server").Value;
                _database = att.Attribute("database").Value;
                _uid = att.Attribute("uid").Value;
                _password = att.Attribute("password").Value;
                _code = att.Attribute("code").Value;
            }
        }

However, I don't seem to be getting the correct output. 但是,我似乎没有得到正确的输出。 I am getting an error message which tells me _server is null. 我收到一条错误消息,告诉我_server为空。 Any idea why? 知道为什么吗? I don't think I am correctly referencing the XML attribute values I want to get a hold of. 我认为我没有正确引用要保留的XML属性值。

One clean approach that you can use: 您可以使用一种干净的方法:

var values = doc.XPathSelectElements("//Connection[@name='default']")
                .Single()
                .Elements("Attribute")
                .ToDictionary(el => (string)el.Attribute("name"),
                              el => (string)el.Attribute("value"));

_server = values["server"];
_database = values["database"];
_uid = values["uid"];
_password = values["password"];
_code = values["code"];

values is an IDictionary<string, string> , so you can use it to retrieve any additional attributes that are added, without modifying the original LINQ code. valuesIDictionary<string, string> ,因此您可以使用它来检索添加的任何其他属性,而无需修改原始LINQ代码。

The issue is that you are looping through elements called Attribute and trying to find XML attributes there. 问题是您正在遍历称为Attribute元素并尝试在其中查找XML属性。 Your logic would indicate that there should be all 5 XML attributes on each XML element called Attribute. 您的逻辑将指示在每个称为Attribute的XML元素上应该有全部5个XML属性。 Try using such code instead: 尝试改用以下代码:

var values = doc.XPathSelectElements("//Connection[@name='default']");
_server = values.Elements("Attribute")   //look for an element called Attribute
             .Where(el => el.Attribute("name").Value == "server")  //which has attribute name="server"
             .Single()    //there should be only single element
             .Attribute("value").Value; //get the value of attribute value
// Repeat that for all other attributes (_database, _uid, etc.)

There is no attributes named "server", "database", "uid", "password" or "code". 没有名为“服务器”,“数据库”,“ uid”,“密码”或“代码”的属性。 They're all values of the attributes named "name" which means you call Attribute("name") and not the value of it. 它们都是名为“ name”的属性的值,这意味着您调用Attribute(“ name”)而不是其值。 Ex. 例如

var attrVal = attr.Attribute("name").Value;
if (attrVal == "server")
    _server = attrVal.Value;
// ... etc

In case the above doesn't work try this. 如果上述方法不起作用,请尝试此操作。

var attrVal = attr.Attribute("name").Value;
if (attrVal == "server")
    _server = attr.Attribute("value").Value;
// ... etc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM