我想弄清楚如何在XmlDocument
找到字符串的所有匹配项。
XmlNodeList results
= document.SelectNodes("Products/Product/fn:matches(.,'" + SearchWord + "')");
我试图比较产品的innerText
。
上面的示例虽然不起作用,但我想我使用XPath函数的方式非常错误。
答案 0 :(得分:4)
评估此XPath 1.0表达式(您知道matches()
是XPath 2.0函数并且在.NET中不受支持):
Products/Product/descendant::*[contains(text(), 'YourSearchWord')]
这将选择具有text-node-child的所有元素,该text-node-child包含字符串'YourSearchWord'
,并且是Product
元素的后代,该元素是Products
元素的子元素。当前(上下文)节点的子节点。
您可以使用:
撰写XPath表达式string.Format("Products/Product/descendant::*[contains(text(), '{0}')]",
SearchWord )
但是,如果从用户输入获得SearchWord
,建议永远不要将其包含在骨干字符串中,以避免XPath注入。
如果是这种情况,建议的方法是使用预编译的XPath表达式,其中用户输入将作为变量引用,并且此变量的值将从XPath评估上下文中消耗。
有关如何防止XPath注入的更多详细信息,请参阅此答案:
答案 1 :(得分:1)
假设你有以下xml
<Names>
<Name>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
</Name>
<Name>
<FirstName>James</FirstName>
<LastName>White</LastName>
</Name>
</Names>
要使所有节点都使用XPath表达式/名称/名称。第一个斜杠表示该节点必须是根节点。 SelectNodes方法返回包含节点的集合XmlNodeList。要获取子节点的值,您只需使用节点名称索引XmlNode:xmlNode [“FirstName”]。InnerText。
XmlDocument xml = new XmlDocument();
xml.LoadXml(myXmlString); // suppose that myXmlString contains "<Names>...</Names>"
XmlNodeList xnList = xml.SelectNodes("/Names/Name");
foreach (XmlNode xn in xnList)
{
string firstName = xn["FirstName"].InnerText;
string lastName = xn["LastName"].InnerText;
Console.WriteLine("Name: {0} {1}", firstName, lastName);
}
输出结果为:
姓名:约翰史密斯 姓名:James White
以此为例/起点。感谢
答案 2 :(得分:0)
如果我正确理解您的问题,您可以使用以下内容:
"Products/Product/[.='" + SearchWord + "']"
或使用contains()
,starts-with()
或normalize-space()
等功能(修剪并用一个空格替换连续的空格)
"Products/Product/[contains(normalize-space(.), '" + SearchWord + "')]"
答案 3 :(得分:0)
给定的表达式求值为布尔值,而不是节点集。我假设 您想检查ProjectName是否等于参数化 文本。在这种情况下,您需要编写
//ErrorTable/ProjectName[text()='{0}']
这将为您提供与给定节点匹配的所有节点(节点集)的列表 条件。这个列表可能是空的,在这种情况下C#-Expression in 你的样本将返回null。
作为事后的想法:你可以使用原始的xpath表达式,但是 不是使用SelectSingleNode,而是使用Evaluate,如下所示:
(bool)xmlDocument.CreateNavigator().Evaluate(String.Format("//ErrorTable/ProjectName/text()='{0}'", projectName));