也许有人可以帮助我。我需要两种方法。
第一个应该打开一个xml文件并获取具有给定参数的所有节点,即:
XML文件(file.xml):
<Menu id="1" Name="myMenu">
<MenuItem Header="Header 1" Name="header1" />
<MenuItem Header="Header 2" Name="header2">
<MenuItem Header="subHeader 2.1" Name="header2_1">
<MenuItem Header="subsubHeader 2.1.1" Name="header2_1_1" />
</MenuItem>
</MenuItem>
<MenuItem Header="Header 3" Name="header3" />
</Menu>
所以,现在我需要用这样的方法从xml中获取值:
public static List<string, string>ReadXML(string filename, string node, string[] attributes, bool searchSubNodes);
调用方法示例:ReadXMLValues("file.xml", "MenuItem", new string[] {"Header", "Name"}, true);
这将返回两个字符串的列表,如:
"Header 1", "header1"
"Header 2", "header2"
"subHeader 2.1", "header2_1" <-- this should be in the list only if searchSubNodes is enabled!
"subsubHeader 2.1.1", "header2_1_1" <-- the same for this one!!!
"Header 3", "header3"
这是阅读部分,现在是写作部分:
filename与上面的file.xml相同。 public static void WriteXML(string filename,string node,List attributes);
现在假设file.xml有空标题属性,如下所示:
<Menu id="1" Name="myMenu">
<MenuItem Header="" Name="header1" />
<MenuItem Header="" Name="header2">
我需要将值放入标题中,finall结果应如下所示:
<Menu id="1" Name="myMenu">
<MenuItem Header="Header 1" Name="header1" />
<MenuItem Header="Header 2" Name="header2">
这样的事可能吗??? C#大师和其他知道如何做的人请请帮助我!我不知道怎么做。
祝你好运!
答案 0 :(得分:1)
您可以使用XPath进行所有搜索。
XmlNodeList nodes = doc.SelectNodes("/Menu/MenuItem");
在这种情况下,nodes
将包含作为顶级MenuItem
元素子元素的所有Menu
元素。
XmlNodeList nodes = doc.SelectNodes("/Menu/MenuItem | /Menu/MenuItem/MenuItem");
在这种情况下,nodes
将包含所有MenuItem
元素,这些元素属于Menu
或属MenuItem
的{{1}}个孩子。< / p>
您还可以找到不超过1 Menu
祖先的所有MenuItem
个节点:
MenuItem
或者您可以找到所有XmlNodeList nodes = doc.SelectNodes("//MenuItem[count(ancestor::MenuItem) < 2]");
个节点:
MenuItem
但是,您选择选择它们,处理元素的方式相同:
XmlNodeList nodes = doc.SelectNodes("//MenuItem");
因此,这表明您可以将此方法封装为具有您建议的签名的方法:
foreach (XmlElement elm in nodes)
{
myList.Add(new[] { elm.GetAttribute("Header"), elm.GetAttribute("Name") });
}
答案 1 :(得分:0)
编辑:
要使用XPath选择具有给定节点名称和两个给定属性的所有节点,请使用以下XPath表达式(我不知道是否有更好的方法来执行此操作,但这可行):
//NodeName[@FirstAttributeName][@SecondAttributeName]
在代码中你可以这样做(对于你的例子中的MenuItems)。我更新了代码,使您在文档中放置的命名空间以前缀“x”表示。此外,XPath表达式已更新为在节点之前使用该前缀。
XPathDocument doc = new XPathDocument("data2.xml");
XPathNavigator nav = doc.CreateNavigator();
XmlNamespaceManager mgr = new XmlNamespaceManager(nav.NameTable);
mgr.AddNamespace("default", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
XPathNodeIterator iterator = nav.Select("//default:MenuItem[@Header][@Name]", mgr);
while (iterator.MoveNext())
{
Console.Write(iterator.Current.GetAttribute("Header", ""));
Console.Write(iterator.Current.GetAttribute("Name", ""));
Console.Write(Environment.NewLine);
}
=====
你必须使用XPath吗?您可以为Menu / MenuItem创建映射到XML的类,如下所示:
public class Menu
{
public int Id { get; set; }
public string Name { get; set; }
public List<MenuItem> SubItems { get; set; }
}
public class MenuItem
{
public string Header { get; set; }
public string Name { get; set; }
public List<MenuItem> SubItems { get; set; }
}
然后让XMLSerializer为你完成工作(它可以同时做,读,写)。之后,您可以将过滤应用于内存列表(例如,使用Linq-To-Objects)。
如果您想使用XPath执行此操作,Codeproject article可能会有所帮助。
答案 2 :(得分:0)
两种解决方案都有效。但是当搜索到的节点出现之前,就像这样:
<MenuItem x:Class="Test.Win"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/Test" <--this line make problems!
Header="Main" Name="Main">
<Menu id="1" Name="myMenu">
<MenuItem Header="Header 1" Name="header1" />
<MenuItem Header="Header 2" Name="header2">
<MenuItem Header="subHeader 2.1" Name="header2_1">
<MenuItem Header="subsubHeader 2.1.1" Name="header2_1_1" />
</MenuItem>
</MenuItem>
<MenuItem Header="Header 3" Name="header3" />
</Menu>
</MyNode>
然后解决方案不起作用。如何只删除架构线或只是跳过它或类似的东西
你们中的某些人可能知道为什么以及如何解决这个问题?
问候!