0

私はいくつかのHTMLを持っています、例えば:

<%@ Page Title="About Us" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="ContentManagedTargetPage.aspx.cs" Inherits="xxx.ContentManagedTargetPage" %>
<%@ Register TagPrefix="CxCMS" Namespace="xxx.ContentManagement.ASPNET.UI" Assembly="xxx.ContentManagement.ASPNET" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>
        Content Managed
    </h2>
    <p>
        Put content here.
        [<CxCMS:ContentManagedPlaceHolder Key="keyThingy" runat="server" />]
    </p>
</asp:Content>

そして、CxCMS:ContentManagedPlaceHolder要素のすべてのインスタンスを検索したいと思います。

私はHTMLAgilityPackを使用しています。これが最適と思われます。

ただし、[meagre]のドキュメントを見ても、コードを機能させることができません。

私は以下が機能することを期待します:

string searchForElement = "CxCMS:ContentManagedPlaceHolder";
IEnumerable<HtmlNode> contentPlaceHolderHtmlNodes = HtmlDocument.DocumentNode.Descendants(searchForElement);
int count = contentPlaceHolderHtmlNodes.Count();                

しかし、私は何も返されません。

DescendantsOrSelfに変更すると、ドキュメントノード「#document」が返されます。これは正しくありません。

string searchForElement = "CxCMS:ContentManagedPlaceHolder";
IEnumerable<HtmlNode> contentPlaceHolderHtmlNodes = HtmlDocument.DocumentNode.DescendantsOrSelf(searchForElement);
int count = contentPlaceHolderHtmlNodes.Count();                

LINQも使用してみました:

string searchForElement = "CxCMS:ContentManagedPlaceHolder";
IEnumerable<HtmlNode> contentPlaceHolderHtmlNodes = HtmlDocument.DocumentNode.DescendantsOrSelf().Where(q=>q.Name==searchForElement);
int count = contentPlaceHolderHtmlNodes.Count();                

これらの方法はどちらも機能しないため、代わりにSelectNodesの使用に移りました。

string searchForElement = "CxCMS:ContentManagedPlaceHolder";
string xPath="//"+searchForElement // "//CxCMS:ContentManagedPlaceHolder"
var nodes= HtmlDocument.DocumentNode.SelectNodes(xPath);

これは例外をスローします:「名前空間マネージャーまたはXsltContextが必要です。このクエリにはプレフィックス、変数、またはユーザー定義関数があります。」HtmlDocumentオブジェクトに名前空間管理を追加する方法が見つかりません。

ここで何が欠けていますか?DescendantsOrSelf()メソッドは、「p」などの「標準」HTMLタグを使用している場合は機能しますが、私が持っているものは機能しません。確かにそれはうまくいくはずですか?(する必要があります!)

4

2 に答える 2

1

いつものように私は1時間かそこら遊んで過ごします、私は質問をします、そして私はそれを数秒後に理解します。

DescendantsOrSelf()を使用して検索する場合、ノード名は小文字にする必要があります。

于 2010-06-16T17:26:21.907 に答える
0

あなたの例は実際にはASPXです。そのページの出力を解析している場合、<CxCMS:ContentManagedPlaceHolder Key="keyThingy" runat="server" />実際にクライアント側でそれとしてレンダリングされるかどうかは疑わしいです。クライアントでhtmlソースを確認し、に対応する出力タグを見つけて、<CxCMS:ContentManagedPlaceHolder Key="keyThingy" runat="server" />でそれらを使用しHtmlDocument.DocumentNode.Descendantsます。

一方、ASPXソースを解析する場合はHtmlDocument.DocumentNode.Descendants、HtmlAgilityPackがそれを認識するように入力を微調整する必要がありますが、ASPX!= htmlであり、HtmlAgilityPackが解析用に構築されているとは思わないことに注意してください。それ。

編集:HtmlAgilityPackソースコードのHtmlNode.csを見ると、次の2つのセクションがあるため、小文字にする必要があることは正しいようです。

    /// <summary>
    /// Gets or sets this node's name.
    /// </summary>
    public string Name
    {
        get
        {
            if (_name == null)
            {
                Name = _ownerdocument._text
                                     .Substring(_namestartindex, _namelength);
            }
            return _name != null ? _name.ToLower() : string.Empty;
        }
        set { _name = value; }
    }

    /// <summary>
    /// Get all descendant nodes with matching name
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public IEnumerable<HtmlNode> Descendants(string name)
    {
        foreach (HtmlNode node in Descendants())
            if (node.Name == name)
                yield return node;
    }

_name.ToLower()のゲッターにあることに注意してください。メソッドでNameは大文字と小文字が区別if (node.Name == name)されDecendantsます。DescendantsAndSelfこれは、、、ElementおよびElementsメソッドを使用したのと同じチェックです。

于 2010-06-16T17:26:45.910 に答える