我有以下xml:
<?xml version="1.0" encoding="utf-8" ?>
<layout>
<menu name="Employees" url="Employees.aspx" admin="0">
</menu>
<menu name="Projects" url="Projects.aspx" admin="1">
</menu>
<menu name="Cases" url="Cases.aspx" admin="1">
</menu>
<menu name="CaseView" url="CaseView.aspx" admin="1" hidden="1" parent="Projects">
</menu>
<menu name="Management" url="" admin="1">
<item name="Groups" url="Groups.aspx" admin="1" parent="Management"/>
<item name="Statuses" url="Statuses.aspx" admin="1"/>
</menu>
</layout>
这里我有CaseView和Groups都有'父'属性。
目前我这样迭代:
IEnumerable<XElement> menus =
doc.Element("layout").Elements();
foreach (var menu in menus)
{
string name = menu.Attribute("name").Value;
string active = "";
string url = menu.Attribute("url").Value;
if(activePage == url)
{
active = "class=\"active\"";
}
...
我想要的是:
if(activePage == url || ActiveIsChildOf(name, activePage))
{
active = "class=\"active\"";
}
本质上,此方法需要查找是否存在具有activePage作为其url属性的元素。如果是,请查看它是否具有父属性;如果是,请检查父==名称。
有没有办法按属性或其他东西找到元素? 例如:
XElement e = doc.GetByAttribute("url",activePage)
由于
答案 0 :(得分:1)
如果xpath太神秘,可以使用LINQ:
IEnumerable<XElement> hits =
(from el in XMLDoc.root.Elements("item")
where (string)el.Attribute("url") == activePage
select el);
或者像这样:
XElement xml = XElement.Load(file);
XElement xele = xml.Elements("item").FirstOrDefault(e => ((string)e.Attribute("url")) == activePage);
if(null != xele )
{
// do something with it
}
你可能希望它不区分大小写:
XElement xml = XElement.Load(file);
XElement xele = xml.Elements("item").FirstOrDefault(e => StringComparer.OrdinalIgnoreCase.Equals((string)e.Attribute("url") , activePage));
if(null != xele )
{
// do something with it
}
如果你想要菜单和项目,请使用:
XElement xml = XElement.Load(file);
XElement xele = xml.Elements().FirstOrDefault(e => StringComparer.OrdinalIgnoreCase.Equals((string)e.Attribute("url") , activePage));
if(null != xele )
{
// do something with it
}
答案 1 :(得分:1)
由于您使用的是Linq to XML,因此可以使用Descendants
方法 - 它返回所有子元素,而不仅仅是直接子元素。之后,您可以使用LINQ过滤结果。
XDocument doc;
string activePage;
var activeMenu = doc.Descendants("menu")
.FirstOrDefault(o => o.Attribute("url").Value == activePage);
如果您不能保证源XML不具有所有菜单元素的此类属性,则可能需要检查o.Attribute("url")
是否不返回null
(当属性不存在时)。
您还可以跳过Descendants()
的参数来检查样本数据中的所有元素,以便检查菜单和项目元素。例如:
var activeMenu = doc.Descendants()
.Where(o => o.Name == "menu" || o.Name == "item")
.FirstOrDefault(o => o.Attribute("url").Value == activePage);
答案 2 :(得分:0)
您只需使用xPath
即可。它是XML
的查询语言。
您可以制定以下内容:
var xDoc = new XmlDocument();
xDoc.Load("XmlFile.xml");
//Fetch your node here
XmlNode = xDoc.SelectSingleNode(/layout/menu[@url='activepage'][1]);
它返回一组节点,索引1用于获取给定集合的第一个节点。
如果您想要所有匹配的节点,可以随时使用xDoc.SelectNodes
。
由于您使用的是LINQ
,因此只需添加System.Xml.XPath
并选择XPathSelectElement
或XPathSelectElements
的节点。
答案 3 :(得分:0)
你可以用XPath做到这一点:
doc.SelectNodes("//*[@url='" + activePage + "']")
它会返回{strong>所有文件中activePage
为url
属性的文档。
答案 4 :(得分:0)
不区分大小写的搜索示例,将xml转换为字典:
Dim expandos = XDocument.Parse(Request("Xml")).Root.Elements.Select(
Function(e)
Dim expando As Object = New ExpandoObject,
dic = e.Attributes.ToDictionary(Function(a) a.Name.LocalName, Function(a) a.Value,
StringComparer.InvariantCultureIgnoreCase)
expando.PedidoId = dic("PedidoId")
expando.FichaTecnicaModeloId = dic("FichaTecnicaModeloId")
expando.Comodo = dic("Comodo")
expando.Cliente = dic("Cliente")
Return expando
End Function)