Kann HtmlAgilityPack mit einer XML-Datei umgehen, die mit einer XSL-Datei geliefert wird, um HTML zu rendern?

c# html-agility-pack

Frage

Ich frage mich, wie HtmlAgilityPack eine XML-Datei liest, die eine xsl-Datei enthält, um HTML zu rendern. Gibt es irgendwelche Einstellungen für die HtmlDocument-Klasse, die dabei helfen könnten, oder muss ich eine Möglichkeit finden, die Umwandlung auszuführen, bevor sie mit HtmlAgiliyPack geladen wird? Wenn ja, kennt jemand eine gute Bibliothek oder Methode für eine solche Transformation? Im Folgenden finden Sie ein Beispiel für eine Website, die xml mit xls-Datei und den Code, den ich verwenden möchte, zurückgibt.

var uri = new Uri("http://www.skechers.com/");
var request = (HttpWebRequest)WebRequest.Create(url);
var cookieContainer = new CookieContainer();

request.CookieContainer = cookieContainer;
request.UserAgent = @"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5";
request.Method = "GET";
request.AllowAutoRedirect = true;
request.Timeout = 15000;

var response = (HttpWebResponse)request.GetResponse();
var page = new HtmlDocument();
page.OptionReadEncoding = false;
var stream = response.GetResponseStream();
page.Load(stream); 

Dieser Code wirft keine Fehler, aber das XML wird geparst und nicht die Umwandlung, was ich will.

Akzeptierte Antwort

Html Agility Pack kann Ihnen hier in zwei Punkten helfen:

1) es ist einfacher, eine Xml-Verarbeitungsanweisung damit zu bekommen, wie es die PI-Daten als Html analysiert, so dass es in Attribute umgewandelt wird

2) HtmlDocument implementiert IXPathNavigable, so dass es direkt von der .NET Xslt-Transformations-Engine transformiert werden kann.

Hier ist ein Code, der funktioniert. Ich musste einen speziellen XmlResover hinzufügen, um Xslt-Transformation richtig zu behandeln, aber ich denke, das ist spezifisch für diesen Fall.

public static void DownloadAndProcessXml(string url, string userAgent, string outputFilePath)
{
    using (XmlTextWriter writer = new XmlTextWriter(outputFilePath, Encoding.UTF8))
    {
        DownloadAndProcessXml(url, userAgent, writer);
    }
}

public static void DownloadAndProcessXml(string url, string userAgent, XmlWriter output)
{
    UserAgentXmlUrlResolver resolver = new UserAgentXmlUrlResolver(url, userAgent);

    // WebClient is an easy to use class.
    using (WebClient client = new WebClient())
    {
        // download Xml doc. set User-Agent header or the site won't answer us...
        client.Headers[HttpRequestHeader.UserAgent] = resolver.UserAgent;
        HtmlDocument xmlDoc = new HtmlDocument();
        xmlDoc.Load(client.OpenRead(url));

        // determine xslt (note the xpath trick as Html Agility Pack does not support xml processing instructions)
        string xsltUrl = xmlDoc.DocumentNode.SelectSingleNode("//*[name()='?xml-stylesheet']").GetAttributeValue("href", null);

        // download Xslt doc
        client.Headers[HttpRequestHeader.UserAgent] = resolver.UserAgent;
        XslCompiledTransform xslt = new XslCompiledTransform();
        xslt.Load(new XmlTextReader(client.OpenRead(url + xsltUrl)), new XsltSettings(true, false), null);

        // transform Html/Xml doc into new Xml doc, easy as HtmlDocument implements IXPathNavigable
        // note the use of a custom resolver to overcome this Xslt resolve requests
        xslt.Transform(xmlDoc, null, output, resolver);
    }
}

// This class is needed during transformation otherwise there are errors.
// This is probably due to this very specific Xslt file that needs to go back to the root document itself.
public class UserAgentXmlUrlResolver : XmlUrlResolver
{
    public UserAgentXmlUrlResolver(string rootUrl, string userAgent)
    {
        RootUrl = rootUrl;
        UserAgent = userAgent;
    }

    public string RootUrl { get; set; }
    public string UserAgent { get; set; }

    public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
    {
        WebClient client = new WebClient();
        if (!string.IsNullOrEmpty(UserAgent))
        {
            client.Headers[HttpRequestHeader.UserAgent] = UserAgent;
        }
        return client.OpenRead(absoluteUri);
    }

    public override Uri ResolveUri(Uri baseUri, string relativeUri)
    {
        if ((relativeUri == "/") && (!string.IsNullOrEmpty(RootUrl)))
            return new Uri(RootUrl);

        return base.ResolveUri(baseUri, relativeUri);
    }
}

Und du nennst es so:

    string url = "http://www.skechers.com/";
    string ua = @"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5";
    DownloadAndProcessXml(url, ua, "skechers.html");

Beliebte Antwort

Sie sollten die Ausgabe von XML und XSLT rendern. Um dies zu tun, müssen Sie das XML herunterladen, und Sie haben das bereits getan. Analysieren Sie als Nächstes den XML-Code, um die XSL-Referenz zu identifizieren. Dann müssen Sie die XSL herunterladen und diese auf das XML-Dokument anwenden.

Diese Links können nützlich sein



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum