如何使用带SeleniumWebDriver的XPath提取XML数据

如何使用带SeleniumWebDriver的XPath提取XML数据,xpath,selenium,selenium-webdriver,Xpath,Selenium,Selenium Webdriver,我正在使用SeleniumWebDriver(2.31.2.0版)(.Net),并试图提取从“driver.PageSource”返回的元素(XML) 我的问题:如何使用下面的xpath获取项目列表。 我可以使用XPATH插件在FF中玩,但同样的代码在SeleniumWebDriver中不起作用 有什么帮助吗 以下是我在Selenium Webdriver中的代码: var driver = new FirefoxDriver(); driver.Navigate().GoToUrl("http

我正在使用SeleniumWebDriver
(2.31.2.0版)
(.Net),并试图提取从“driver.PageSource”返回的元素(XML)

我的问题:如何使用下面的xpath获取项目列表。 我可以使用XPATH插件在FF中玩,但同样的代码在SeleniumWebDriver中不起作用

有什么帮助吗

以下是我在Selenium Webdriver中的代码:

var driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://website_name/languages.xml");
string _page_source = driver.PageSource;
ReadOnlyCollection<IWebElement> webElements = _page_source.FindElementsByXPath("//response//results//items/vList");
var-driver=新的FirefoxDriver();
driver.Navigate().gotour(“http://website_name/languages.xml");
字符串_page_source=driver.PageSource;
ReadOnlyCollection webElements=_page_source.FindElementsByXPath(“//response//results//items/vList”);
我的xml如下所示:

<response xmlns="http://schemas.datacontract.org/2004/07/myproj.cnn.com">
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <meta>

    </meta>
    <results i:type="vList">
        <name>Language</name>
        <queryValue>language</queryValue>
        <displayOrder>0</displayOrder>
        <items>
            <vList>
                <name>English</name>
                <displayName>English</displayName>
                <displayOrder>0</displayOrder>
                <items />
            </vList>
            <vList>
                <name>Swedish</name>
                <displayName>Swedish</displayName>
                <displayOrder>1</displayOrder>
                <items />
            </vList>
        </items>
    </results>
</response>

xmlns:i=”http://www.w3.org/2001/XMLSchema-instance">
语言
语言
0
英语
英语
0
瑞典的
瑞典的
1.

您发布的XML输入声明了一个命名空间:
xmlns=”http://schemas.datacontract.org/2004/07/myproj.cnn.com“
。请参见下一行:

<response xmlns="http://schemas.datacontract.org/2004/07/myproj.cnn.com">
要获取所有
displayName
元素,您可以使用:

/foo:response/foo:results/foo:items/foo:vList/foo:displayName
如果您想要元素的总计数而不是元素列表,可以将
count()

count(/foo:response/foo:results/foo:items/foo:vList)
count(/foo:response/foo:results/foo:items/foo:vList/foo:displayName)

您使用的XPath中有很多
/
。如果确实有必要,请仅使用
/
,因为它将扫描整个文件,并且如果您已经知道路径,则需要比必要时更多的资源。

您可以使用selenium浏览并获取xml,但使用.net类处理xml

driver.PageSource
属性是一个字符串,您应该直接使用.Net类来解析所表示的xml。此外,字符串对象上没有方法
FindElementsByXPath()
,除非这是您编写的扩展方法

使用selenium中的
driver.PageSource
读取xml

var driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://website_name/languages.xml");
XmlReader reader = XmlReader.Create(driver.PageSource);
或者,通过使用直接浏览url来读取xml

XmlReader reader = XmlReader.Create("http://website_name/languages.xml");
然后使用下面的代码来解析和读取xml。 需要注意的关键点是如何将名称空间信息提供给xpath

//load xml document
XElement xmlDocumentRoot = XElement.Load(reader);
//also add the namespace infn, chose a prefix for the default namespace
XmlNameTable nameTable = reader.NameTable;
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(nameTable);
namespaceManager.AddNamespace("a", "http://schemas.datacontract.org/2004/07/myproj.cnn.com");

//now query with your xml - remeber to prefix the default namespace
var items = xmlDocumentRoot.XPathSelectElements("//a:results/a:items/a:vList", namespaceManager);

Console.WriteLine("vlist has {0} items.", items.Count());

foreach (var item in items)
{
Console.WriteLine("Display name: {0}", item.XPathSelectElement("a:displayName",namespaceManager).Value);
}
// OR get a list of all display names using linq
var displayNames = items.Select(x => x.XPathSelectElement("a:displayName", namespaceManager).Value).ToList();
要使上述功能正常工作,您将需要以下名称空间:

using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

您想要的值是什么?因此,我将查找
vList
displayName
的总数。谢谢,我无法控制xml,也无法将名称空间添加到该xml,我有哪些选项,我的意思是,如果我没有名称空间,那么我将无法使用?@AbuHamzah当然,您无法控制输入XML。您也不需要向输入XML添加名称空间。我是说输入XML已经有了默认的名称空间。Selenium代码中应该使用此名称空间,以便能够使用XPathFaiz:当我尝试执行
string\u pageSource=driver.pageSource时,路径中出现了
非法字符;XmlReader=XmlReader.Create(_pageSource)通过将xml保存到文件并使用
XmlReader=XmlReader.Create(@“D:\test\file.xml”)执行基本测试。我已经测试了这个,它是有效的。尽管如此,您之前发布的xml需要修复-两个名称空间之间的
response
标记被错误地关闭。最后,我只添加了两行代码,以便使用(var streader=new StringReader(_pageSource))和(var reader=XmlReader.Create(streader))实现该功能{……}
//load xml document
XElement xmlDocumentRoot = XElement.Load(reader);
//also add the namespace infn, chose a prefix for the default namespace
XmlNameTable nameTable = reader.NameTable;
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(nameTable);
namespaceManager.AddNamespace("a", "http://schemas.datacontract.org/2004/07/myproj.cnn.com");

//now query with your xml - remeber to prefix the default namespace
var items = xmlDocumentRoot.XPathSelectElements("//a:results/a:items/a:vList", namespaceManager);

Console.WriteLine("vlist has {0} items.", items.Count());

foreach (var item in items)
{
Console.WriteLine("Display name: {0}", item.XPathSelectElement("a:displayName",namespaceManager).Value);
}
// OR get a list of all display names using linq
var displayNames = items.Select(x => x.XPathSelectElement("a:displayName", namespaceManager).Value).ToList();
using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;