我有一个xml文件,如下所示
<Games>
<Game>
<name>Tzoker</name>
<file>tzoker1</file>
</Game>
<Game>
<file>lotto770</file>
</Game>
<Game>
<name>Proto</name>
<file>proto220</file>
</Game>
</Games>
我想获取每个Game节点的名称和文件项的值。 使用此查询很容易。
string query = String.Format("//Games/Game");
XmlNodeList elements1 = xml.SelectNodes(query);
foreach (XmlNode xn in elements1)
{
s1 = xn["name"].InnerText;
s2 = xn["file"].InnerText;
}
问题是有些节点没有名称项。所以上面的代码不起作用。 我已使用以下代码解决了该问题
string query = String.Format("//Games/Game/name");
XmlNodeList elements1 = xml.SelectNodes(query);
foreach (XmlNode xn in elements1)
{
s1 = xn.InnerText;
string query1 = String.Format("//Games/Game[name='{0}']/file", s1);
XmlNodeList elements2 = xml.SelectNodes(query1);
foreach (XmlNode xn2 in elements2)
{
s2 = xn2.InnerText;
}
}
问题在于存在两个或更多节点具有相同名称值的情况。因此,s2变量将获取循环找到的最后一个节点的文件值。所以,我想找到一种方法来获取当前名称项的兄弟文件值。我怎么能这样做?我尝试移动到当前节点的父节点,然后移动到文件项但是没有成功使用以下代码。
string query = String.Format("//Games/Game/name");
XmlNodeList elements1 = xml.SelectNodes(query);
foreach (XmlNode xn in elements1)
{
s1 = xn.InnerText;
string query1 = String.Format("../file");
XmlNodeList elements2 = xml.SelectNodes(query1);
foreach (XmlNode xn2 in elements2)
{
s2 = xn2.InnerText;
}
}
我希望有一个解决方案。
答案 0 :(得分:0)
如果我理解正确,你想找到所有有名字的游戏。你可以使用XPath做到这一点。这是一个使用LINQ to XML的解决方案。我觉得比XmlDocument
更容易使用
var xDocument = XDocument.Parse(xml);
var games = xDocument
.Root
.XPathSelectElements("Game[child::name]")
.Select(
gameElement => new {
Name = gameElement.Element("name").Value,
File = gameElement.Element("file").Value
}
);
选择具有<Game>
子元素的所有<name>
元素的XPath为Game[child::name]
。
答案 1 :(得分:0)
您可以使用Game[name]
将Game
元素过滤为具有子元素name
的元素。这是可能的,因为child::
是默认轴,当没有提到明确的轴时将隐含这些轴。进一步扩展以检查子元素file
,就像Game[name and file]
一样简单:
string query = String.Format("//Games/Game[name]");
XmlNodeList elements1 = xml.SelectNodes(query);
foreach (XmlNode xn in elements1)
{
s1 = xn["name"].InnerText;
s2 = xn["file"].InnerText;
}
现在从字面上回答你的问题,你可以使用following-sibling::
轴来获取当前上下文元素之后的兄弟元素。因此,如果上下文元素为name
,则可以following-sibling::file
返回同级file
元素。
您使用../file
的尝试也应该有效。唯一的问题是,您的代码在xml
XmlDocument
上执行XPath,而不是在当前name
元素上执行它:
XmlNodeList elements2 = xn.SelectNodes("../file");