Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7081385
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T06:54:52+00:00 2026-05-28T06:54:52+00:00

I found I could generate XDocument object from html by using SgmlReader.SL. https://bitbucket.org/neuecc/sgmlreader.sl/ The

  • 0

I found I could generate XDocument object from html by using SgmlReader.SL.
https://bitbucket.org/neuecc/sgmlreader.sl/

The code is like this.

public XDocument Html(TextReader reader)
{
    XDocument xml;
    using (var sgmlReader = new SgmlReader { DocType = "HTML", CaseFolding = CaseFolding.ToLower, InputStream = reader })
    {
        xml = XDocument.Load(sgmlReader);
    }
    return xml;
}

Also we can get src attributes of img tags from the XDocument object.

var ns = xml.Root.Name.Namespace;

var imgQuery = xml.Root.Descendants(ns + "img")
    .Select(e => new
        {
            Link = e.Attribute("src").Value
        });

And, we can download and convert stream data of image to BASE64 string.

public static string base64String;

WebClient wc = new WebClient();
wc.OpenReadAsync(new Uri(url));  //image url from src attribute
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);

void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    using (MemoryStream ms = new MemoryStream())
    {
        while (true)
        {
            byte[] buf = new byte[32768];
            int read = e.Result.Read(buf, 0, buf.Length);

            if (read > 0)
            {
                ms.Write(buf, 0, read);
            }
            else { break; }
        }
        byte[] imageBytes = ms.ToArray();
        base64String = Convert.ToBase64String(imageBytes);
    }
}

So, What I’d like to do is bellow steps. I’d like to do bellow steps in one method chain like LINQ or Reactive Extensions.

  1. Get src attributes of img tags from XDocument object.
  2. Get image datas from urls.
  3. Generate BASE64 string from image datas.
  4. Replace src attributes by BASE64 string.

The simplest source and output are here.

  • Before

    <html>
    <head>
    </head>
    <body>
        <img src='http://image.com/image.jpg' />
        <img src='http://image.com/image2.png' />
    </body>
    </html>
    
  • After

    <html>
    <head>
    </head>
    <body>
        <img src='data:image/jpg;base64,iVBORw...' />
                <img src='data:image/png;base64,iSDoske...' />
    </body>
    </html>
    

Does anyone know the solution for this?

I’d like to ask experts.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T06:54:53+00:00Added an answer on May 28, 2026 at 6:54 am

    Both LINQ and Rx are designed to promote transformations that result in new objects, not ones that modify existing objects, but this is still doable. You have already done the first step, breaking the task into parts. The next step is to make composable functions that implement those steps.

    1) You mostly have this one already, but we should probably keep the elements around to update later.

    public IEnumerable<XElement> GetImages(XDocument document)
    {
        var ns = document.Root.Name.Namespace;
        return document.Root.Descendants(ns + "img");
    }
    

    2) This seems to be where you have hit a wall from the composability point of view. To start, lets make a FromEventAsyncPattern observable generator. There are already ones for the Begin/End async pattern and standard events, so this will come out somewhere in between.

    public IObservable<TEventArgs> FromEventAsyncPattern<TDelegate, TEventArgs> 
        (Action method, Action<TDelegate> addHandler, Action<TDelegate> removeHandler
        ) where TEventArgs : EventArgs
    {
        return Observable.Create<TEventArgs>(
            obs =>
            {
                //subscribe to the handler before starting the method
                var ret = Observable.FromEventPattern<TDelegate, TEventArgs>(addHandler, removeHandler)
                                    .Select(ep => ep.EventArgs)
                                    .Take(1) //do this so the observable completes
                                    .Subscribe(obs);
                method(); //start the async operation
                return ret;
            }
        );
    }
    

    Now we can use this method to turn the downloads into observables. Based on your usage, I think you could also use DownloadDataAsync on the WebClient instead.

    public IObservable<byte[]> DownloadAsync(Uri address)
    {
        return Observable.Using(
                 () => new System.Net.WebClient(),
                 wc =>
                 {
                    return FromEventAsyncPattern<System.Net.DownloadDataCompletedEventHandler,
                                                 System.Net.DownloadDataCompletedEventArgs>
                              (() => wc.DownloadDataAsync(address),
                               h => wc.DownloadDataCompleted += h,
                               h => wc.DownloadDataCompleted -= h
                              )
                           .Select(e => e.Result);
                    //for robustness, you should probably check the error and cancelled
                    //properties instead of assuming it finished like I am here.
                 });
    }
    

    EDIT: As per your comment, you appear to be using Silverlight, where WebClient is not IDisposable and does not have the method I was using. To deal with that, try something like:

    public IObservable<byte[]> DownloadAsync(Uri address)
    {
        var wc = new System.Net.WebClient();
        var eap = FromEventAsyncPattern<OpenReadCompletedEventHandler,
                                        OpenReadCompletedEventArgs>(
                     () => wc.OpenReadAsync(address),
                     h => wc.OpenReadCompleted += h,
                     h => wc.OpenReadCompleted -= h);
        return from e in eap
               from b in e.Result.ReadAsync()
               select b;
    }
    

    You will need to find an implementation of ReadAsync to read the stream. You should be able to find one pretty easily, and the post was long enough already so I left it out.

    3 & 4) Now we are ready to put it all together and update the elements. Since step 3 is so simple, I’ll just merge it in with step 4.

    public IObservable<Unit> ReplaceImageLinks(XDocument document)
    {
        return (from element in GetImages(document)
                let address = new Uri(element.Attribute("src").Value)
                select (From data in DownloadAsync(address)
                        Select Convert.ToBase64String(data)
                       ).Do(base64 => element.Attribute("src").Value = base64)
               ).Merge()
                .IgnoreElements()
                .Select(s => Unit.Default); 
                //select doesn't really do anything as IgnoreElements eats all
                //the values, but it is needed to change the type of the observable.
                //Task may be more appropriate here.
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Could anyone please explain the following line of code, found on http://docs.openttd.org/ai__cargo_8cpp_source.html return (AICargo::TownEffect)::CargoSpec::Get(cargo_type)->town_effect;
Whilst refactoring some legacy C++ code I found that I could potentially remove some
It looks like a problem which could have simple solution, but I haven't found
I found a javascript plugin that could generate zip files, its called jszip .
I've recently found out about protocol buffers and was wondering if they could be
I'm sure I once found a shell command which could print the common lines
i have this problem: ms-access could not delete and i found a potential solution
I searched through here as best I could and though I found some relevant
I've found ScriptingJsonSerializationSection but I'm not sure how to use it. I could write
I've found a answer how to remove diacritic characters on stackoverflow, but could you

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.