选择具有特定值的子节点

时间:2015-04-29 06:19:58

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

我想检查一下“< city>”在将新城市节点插入xml之前,具有特定值(例如Pathankot)的节点已存在于特定“< user Id =”any“>具有特定Id”的xml文件中。

< users> 
     < user Id="4/28/2015 11:29:44 PM"> 
          <city>Fazilka</city> 
          <city>Pathankot </city> 
          <city>Jalandher</city> 
          <city>Amritsar</city> 
     </user> 
</users> 

为了插入我正在使用以下c#代码

 XDocument xmlDocument = XDocument.Load(@"C:\Users\Ajax\Documents\UserSelectedCity.xml");
        string usrCookieId = Request.Cookies["CookieId"].Value;
xmlDocument.Element("Users")
            .Elements("user")
.Single(x => (string)x.Attribute("Id") == usrCookieId)
             //Incomplete because same named cities can be entered more that once 
             //need to make delete function
            .Add(
            new XElement("city", drpWhereToGo.SelectedValue));

我的问题:

  • 我如何查看天气&lt;城市&GT;具有特定值的节点说 在插入新城市之前,Pathankot已存在于xml文件中 节点。
  • 我在“ XDocument xmlDocument =
    XDocument.Load(@"C:\Users\Ajax\Documents\Visual Studio
    2012\WebSites\punjabtourism.com\UserSelectedCity.xml");"
    这个中使用绝对路径 不允许我将文件移动到新文件夹而不更改
    这条路是不可取的。但如果我使用相对路径 错误发生“访问被拒绝”;

3 个答案:

答案 0 :(得分:1)

我会用这个简单的方法:

var query =
    xmlDocument
        .Root
        .Elements("user")
        .Where(x => x.Attribute("Id").Value == usrCookieId)
        .Where(x => !x.Elements("city").Any(y => y.Value == "Pathankot"));

foreach (var xe in query)       
{
    xe.Add(new XElement("city", drpWhereToGo.SelectedValue));
}

如果可能,最好避免使用.Single(...).First(...)。您的问题的描述听起来并不像您需要使用这些。

答案 1 :(得分:0)

试试这个: -

首先通过指定XML文件所在的物理路径将XML文件加载到- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (object == player && [keyPath isEqualToString:@"status"]) { if (player.status == AVPlayerStatusReadyToPlay) { play.enabled = YES; } } } 对象中。获得对象后,只需使用具有匹配条件的XDocument节点(请注意我使用的是First而不是Single cz,您可能有多个具有相同匹配条件的节点,请参阅Single & First之间的差异)< / p>

First

最后将所需的城市添加到从查询中检索到的节点,并保存XDocument对象。

<强>更新

如果您想首先检查所有条件是否满足,那么只需使用XDocument xmlDocument = XDocument.Load(@"YourPhysicalPath"); xmlDocument.Descendants("user").First(x => (string)x.Attribute("Id") == "1" && x.Elements("city").Any(z => z.Value.Trim() == "Pathankot")) .Add(new XElement("city", drpWhereToGo.SelectedValue)); xmlDocument.Save("YourPhysicalPath"); ,如下所示: -

Any

答案 2 :(得分:0)

我创建了一个扩展来清理它,并使用XPath进行搜索。

public static class MyXDocumentExtensions
{
    public static bool CityExists(this XDocument doc, string cityName)
    {
        //Contains
        //var matchingElements = doc.XPathSelectElements(string.Format("//city[contains(text(), '{0}')]", cityName));
        //Equals
        var matchingElements = doc.XPathSelectElements(string.Format("//city[text() = '{0}']", cityName));

        return matchingElements.Count() > 0;
    }
}

并称之为:

XDocument xmlDocument = XDocument.Load("xml.txt");
var exists = xmlDocument.CityExists("Amritsar");

在评论中扩展您的问题,然后您可以将其用作:

if(!xmlDocument.CityExists("Amritsar"))
{
    //insert city
}

如果要匹配XML中的尾随空格,可以在XPath中使用normalize-space包装text()调用:

var matchingElements = doc.XPathSelectElements(string.Format("//city[normalize-space(text()) = '{0}']", cityName.Trim()));