C# 选择具有特定值的子节点
在将新的城市节点插入xml之前,我想检查具有特定Id的特定“C# 选择具有特定值的子节点,c#,xml,linq,linq-to-xml,C#,Xml,Linq,Linq To Xml,在将新的城市节点插入xml之前,我想检查具有特定Id的特定“下的xml文件中是否已经存在具有特定值(比如Pathankot)”的“”节点 < users> < user Id="4/28/2015 11:29:44 PM"> <city>Fazilka</city> <city>Pathankot </city> <city>Jalan
< users>
< user Id="4/28/2015 11:29:44 PM">
<city>Fazilka</city>
<city>Pathankot </city>
<city>Jalandher</city>
<city>Amritsar</city>
</user>
</users>
我的问题:- 如何检查具有特定值的
节点 插入新城市之前,xml文件中已存在Pathankot 节点李> - 我在“
不允许我在不更改的情况下将文件移动到新文件夹XDocument xmlDocument=
XDocument.Load(@“C:\Users\Ajax\Documents\Visual Studio
2012\WebSites\punjab tourism.com\UserSelectedCity.xml“;”
不可取的道路。但是如果我使用相对路径,
出现错误“拒绝访问”李> - 我在“
XDocument
对象中。一旦有了对象,只需使用匹配条件的第一个
节点(请注意,我使用的是第一个而不是单个cz,您可能有多个具有相同匹配条件的节点,请查看它们之间的差异)
最后,将所需的城市添加到从查询中检索到的节点,并保存XDocument对象
更新:
如果您想首先检查所有标准是否满足,那么只需像这样使用Any
:-
bool isCityPresent = xdoc.Descendants("user").Any(x => (string)x.Attribute("Id") == "1"
&& x.Elements("city").Any(z => z.Value.Trim() == "Pathankot"));
我将创建一个扩展来清理它,并使用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空格包装text()调用:
var matchingElements = doc.XPathSelectElements(string.Format("//city[normalize-space(text()) = '{0}']", cityName.Trim()));
我会使用这个简单的方法:
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(…)
。但是,对您的问题的描述听起来并不需要使用这些 我是否可以在If()下使用此表达式,例如“If(xmlDocument.subjections(“user”).First(x=>(string)x.Attribute(“Id”)==“1”和&x.subjections(“city”).Any(z=>z.Value.Trim()==“Pathankot”)”{//然后不要输入项}@AnilKumar-不,因为如果您想先检查它,然后使用我更新的代码,它将返回一个XElement
而不是布尔值。Thanx它工作得很好!您介意回答我的第二个问题吗?@AnilKumar-在这种情况下,您应该使用Server.MapPath
,但它只有在您的XML中已经存在时才会工作Web应用程序项目。如果(!isCityPresent){//则创建一个条目}我以这种方式使用它,并且它可以工作。不包含XPathSelectElements的定义。我必须使用任何指令或程序集引用吗?是的,您需要添加:使用System.Xml.XPathOk它工作得很好,但是我们可以在更具体的约束下使用xPath。我的意思是说,在上面的代码中,我们发现所有城市节点都具有指定的但是如果我们需要在一个有特定用户的特定目录下找到有特定城市名称的城市呢Id@AnilKumar//user[@id='user\u id\u here']/city[.='cityname\u here']
matchingElements.ToList().ForEach(el=>el.Value)
var matchingElements = doc.XPathSelectElements(string.Format("//city[normalize-space(text()) = '{0}']", cityName.Trim()));
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));
}