Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to bind a nested class property to the attribute of html element with GetEncapsulatedData Method? #505

Closed
rwecho opened this issue Jul 11, 2023 · 4 comments

Comments

@rwecho
Copy link
Contributor

rwecho commented Jul 11, 2023

innerHtmlDocument.LoadHtml(node.InnerHtml);

In most situations, I like to use XPath attribute binding to a Property. But in the nested class, it can not access the parent node, the parent node's attribute often records some important information, like id.

   [HasXPath]
    class TestA
    {
        [XPath("a")]
        public List<Item> Items { get; set; }
        [HasXPath]
        public class Item
        {
            [XPath(".", "href")] //not working
            [SkipNodeNotFound]
            public string Href { get; set; }

            [XPath(".")]
            [SkipNodeNotFound]
            public string Name { get; set; }
        }

    }

    var html = @"
<div>
<div>Hello
<a href='1.html'>1.html</a>
<a href='2.html'>2.html</a>
</div>
<div>World</div>
</div>
";

     var document = new HtmlDocument();
     Document. LoadHtml(html);
     var testA = Document. DocumentNode.GetEncapsulatedData<TestA>();

In the HtmlNode.Encapsulator.cs#L298, Is using OuterHtml better than InnerHtml?

@elgonzo
Copy link
Contributor

elgonzo commented Jul 11, 2023

In the HtmlNode.Encapsulator.cs#L298, Is using OuterHtml better than InnerHtml?

The bug seems to be not adhering to the [XPath] attribute's NodeReturnType value here (the NodeReturnType value is supposed to govern whether InnerText, InnerHtml or OuterHtml is used for producing the result for a property.

HtmlNode.Encapsulator.cs#L298:

innerHtmlDocument.LoadHtml(node.InnerHtml);

isn't the only place exhibiting this issue, HtmlNode.Encapsulator.cs#L180 also forgets to take HasXPathAttribute.NodeReturnType into account:

innerHtmlDocument.LoadHtml(htmlNode.InnerHtml);

After proper support for the HasXPathAttribute.NodeReturnType property has been implemented, then this should work:

[HasXPath]
class TestA
{
      [XPath("a", NodeReturnType = ReturnType.OuterHtml)]    // <--------- setting NodeReturnType here
      public List<Item> Items { get; set; }

      [HasXPath]
      public class Item
      {
          [XPath(".", "href")]
          [SkipNodeNotFound]
          public string Href { get; set; }

          [XPath(".")]
          [SkipNodeNotFound]
          public string Name { get; set; }
      }
}

@elgonzo
Copy link
Contributor

elgonzo commented Jul 11, 2023

Side note: There is a related issue that also warrants fixing when the proper NodeReturnType support is being implemented. Currently, when a property of a simple type like string has a [XPath] attribute with an invalid NodeReturnType value, a bare-bones and non-descript System.Exception is being thrown:

This should to be changed into a meaningful exception with a message that informs about the concrete cause of the exception.

@rwecho
Copy link
Contributor Author

rwecho commented Jul 12, 2023

@elgonzo I created a PR on your advice, please help me review it.

@JonathanMagnan
Copy link
Member

Hello @rwecho ,

We will close this issue has your PR has been merged and now available in the v1.11.50

Best Regards,

Jon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants