2

Selenium Webdriver (ver 2.31.2.0)(.Net) を使用しており、「driver.PageSource」から返される要素 (XML) を抽出しようとしています。

私の質問: 以下の xpath を使用してアイテムのリストを取得する方法。XPATH アドオンを使用して FF で再生できますが、同じコードが Selenium Webdriver では機能しません

助けはありますか?

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");

私の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>
4

2 に答える 2

4

Selenium を使用して xml を参照して取得できますが、.net クラスを使用して xml を操作します。

プロパティは文字列であり、driver.PageSource.Net クラスを直接使用して、表現される xml を解析する必要があります。また、FindElementsByXPath()作成した拡張メソッドでない限り、文字列オブジェクトにはメソッドはありません。

driver.PageSourcefrom seleniumを使用して 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;
于 2013-10-02T04:48:03.123 に答える
1

投稿した XML 入力には名前空間が宣言されています: xmlns="http://schemas.datacontract.org/2004/07/myproj.cnn.com"。次の行を参照してください。

<response xmlns="http://schemas.datacontract.org/2004/07/myproj.cnn.com">

この名前空間にはプレフィックスがないため、プレフィックスのないすべての要素の既定の名前空間になります。つまり、要素<response>や要素<results>などはすべてこの名前空間に属しています。

次を読む: http://www.w3schools.com/xml/xml_namespaces.asp

したがって、コードでは、XPath 評価が機能する前に名前空間を宣言する必要があります。Selenium Webdriver で名前空間を設定する方法はわかりませんが、見つけることができると思います。

名前空間を宣言したら、これを XPath で使用する必要があります。たとえば、XSLT では、次のように名前空間を宣言できます。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:foo="http://schemas.datacontract.org/2004/07/myproj.cnn.com">

名前空間を prefix で宣言しましたfoovListすべての要素を取得するために使用できる XPath は次のようになります。

/foo:response/foo:results/foo:items/foo:vList

使用できるすべての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 には多くの情報が含ま//れています。//完全なファイルをスキャンし、パスが既にわかっている場合は必要以上のリソースを消費するため、本当に必要な場合にのみ使用してください。

于 2013-10-01T19:29:37.867 に答える