选择具有特定值的子节点
Selecting a child node having specific value
我想检查“”节点 'having a specific value (say Pathankot )' 是否已经存在于特定“ 下的 xml 文件中specific 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));
我的问题:
- 我如何检查具有特定值 say 的
节点的天气
在插入新城市之前,Pathankot 已经存在于 xml 文件中
节点。
- 我正在使用绝对路径"
XDocument xmlDocument =<br>
XDocument.Load(@"C:\Users\Ajax\Documents\Visual工作室<br>
2012\WebSites\punjabtourism.com\UserSelectedCity.xml");"
这个
不允许我在不更改的情况下将文件移动到新文件夹
不可取的路径。但是如果我使用相对路径 The
发生错误 "Access Denied";
试试这个:-
首先通过指定 XML 文件所在的物理路径,将 XML 文件加载到 XDocument
对象中。获得对象后,只需获取具有匹配条件的 First
节点(请注意我使用的是 First 而不是 Single cz,您可能有多个具有相同匹配条件的节点,请参阅 Single & First 之间的区别)
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");
最后将所需的城市添加到从查询中检索到的节点并保存 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 中尾随的白色 space,你可以使用 normalize-space 在 XPath 中包装 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(...)
。你的问题的描述听起来并不像你需要使用这些。
我想检查“
< 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));
我的问题:
- 我如何检查具有特定值 say 的
节点的天气 在插入新城市之前,Pathankot 已经存在于 xml 文件中 节点。 - 我正在使用绝对路径"
XDocument xmlDocument =<br> XDocument.Load(@"C:\Users\Ajax\Documents\Visual工作室<br> 2012\WebSites\punjabtourism.com\UserSelectedCity.xml");"
这个 不允许我在不更改的情况下将文件移动到新文件夹
不可取的路径。但是如果我使用相对路径 The
发生错误 "Access Denied";
试试这个:-
首先通过指定 XML 文件所在的物理路径,将 XML 文件加载到 XDocument
对象中。获得对象后,只需获取具有匹配条件的 First
节点(请注意我使用的是 First 而不是 Single cz,您可能有多个具有相同匹配条件的节点,请参阅 Single & First 之间的区别)
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");
最后将所需的城市添加到从查询中检索到的节点并保存 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 中尾随的白色 space,你可以使用 normalize-space 在 XPath 中包装 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(...)
。你的问题的描述听起来并不像你需要使用这些。