他の隠されたスパンを含むスパンから内部テキストを取得する方法?

c# html html-agility-pack

質問

私はいくつかのテストhtmlページを持っています

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Page for test</title>
</head>
<body>
    <div class="r_tr">
        <span class="r_rs">Inner text<span class="otherSpan" style="display: none">text</span></span>
    </div>
</body>
</html>

私は "内部のテキスト"を取得したい。私はHtmlAgilityPackを使用しています。私はこのメソッドを書く

public string GetInnerTextFromSpan(HtmlDocument doc)
{
    const string rowXPath = "//*[@class=\"r_tr\"]";
    const string spanXPath = "//*[@class=\"r_rs\"]";
    string text = null;
    HtmlNodeCollection rows = doc.DocumentNode.SelectNodes(rowXPath);
    foreach(HtmlNode row in rows)
    {
        text = row.SelectSingleNode(spanXPath).InnerText;
        Console.WriteLine("textL {0}", text);
    }
    return text;

}

このメソッドは "Inner texttext"を返します。私は私の問題を説明するためのいくつかの単体テストを書く

[Test]
public void TestGetInnerTextFromSpan()
{
    var client = new PromtTranslatorClient();
    var doc = new HtmlDocument();
    doc.Load(@"testPage.html");
    var text = client.GetInnerTextFromSpan(doc);
    StringAssert.AreEqualIgnoringCase("Inner text", text);
}

結果

Expected string length 10 but was 14. Strings differ at index 10.
  Expected: "Inner text", ignoring case
  But was:  "Inner texttext"
  ---------------------^

受け入れられた回答

私はXPathについてはわかりませんが、ここではLINQを使ったソリューションです:

String inner = (from x in doc.DocumentNode.Descendants()
                where x.Name == "span"
                && x.Attributes["class"].Value == "r_rs"
                select 
                      (from y in x.ChildNodes
                       where y.Name == "#text"
                       select y.InnerText).FirstOrDefault()
                ).FirstOrDefault();

人気のある回答

まず、あなたのspanXPathが間違っています。 //は開始時に "ルートから開始"を意味するので、 row.SelectSingleNode(spanXPath)は、行内ではなく文書内でクラスr_rsを持つ最初の要素を常に提供します。これを解決するために//を削除してください。

次に、 text()はテキストノードのXPathです。あなたは使うことができます

var span = row.SelectSingleNode(spanXPath);
var textNode = span.SelectSingleNode("text()");
text = textNode.InnerText;
Console.WriteLine("textL {0}", text);

foreachループで、選択したスパンの最初のテキストノードを取得します。




ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ