2011-03-21 19 views
5

HtmlAgilityPack'in html oluşturmak için bir xsl dosyası içeren bir xml dosyasını okumasının en iyi yolunu merak ediyordum. HtmlDocument sınıfında bu konuda yardımcı olacak herhangi bir ayar var mı, yoksa HtmlAgiliyPack ile yüklemeden önce dönüştürmeyi yürütmek için bir yol bulmak zorunda mıyım? Eğer ikincisi için evetse, iyi bir kütüphane veya böyle bir dönüşüm için yöntem bilen var mı? Aşağıda xml dosyasını xls dosyası ve kullanmak istediğim kodu döndüren bir web sitesinin örneği yer almaktadır. HtmlAgilityPack, html oluşturmak için bir xsl dosyasıyla birlikte gelen bir xml dosyasını kullanabilir mi?

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); 

Bu kod

hataları atmak değil, ama xml Benim istediğim dönüşümü, ayrıştırılır ve değil alır budur.

+2

, neden hiç HTMLAgilityPack kullanılır? – Cameron

+0

Sayfa özeti, sayfa başlığı ve meta açıklaması ile sayfada img kaynaklarının bir listesini almaya çalışıyorum. Web'den herhangi bir geçerli URL'nin girilmesine izin veriyorum. Yani sorunuzu cevaplamak için, her zaman iyi biçimlendirilmiş xml'm yok ve ben bile olsa, belge başlığı ve açıklaması tutarsız bir şekilde biçimlendirilecek. –

cevap

3
Html çeviklik paketi iki nokta burada size yardımcı olabilir

:

1) o Html olarak PI verileri ayrıştırır gibi onunla bir XML işleme talimatı almak için daha kolay, bu yüzden nitelikler haline dönüştürecek

2) HtmlDocument, IXPathNavigable uygular, bu nedenle doğrudan .NET Xslt dönüştürme motoru tarafından dönüştürülebilir.

İşte bir kod parçası çalışır. Xslt dönüşümünü düzgün bir şekilde işlemek için belirli bir XmlResover eklemeliydim, ancak bu skechers davası için özel olduğunu düşünüyorum.

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); 
    } 
} 

Ve böyle diyoruz: Eğer iyi biçimli XML varsa

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"); 
+0

tekrar teşekkürler, benim amaçlar için düşünüyorum asıl soruya ilk kod parçacığı gibi bir istek oluşturur özel fonksiyon, biraz daha iyi çalışır olması kodudur. Bunun nasıl kodunuzu tavsiye edeceğine dair genel bir rehber düşünüyorum. Btw, HtmlAgilityPack f * #% ing harika. –

+0

Ayrıca elle bir akış oluşturmak zorunda kalmadan HtmlDocument.Load yöntemine bir html dizesi geçirebilmek için havalı olabileceğini de eklemek isterim.Zaten 12 aşırı yüklenme olduğunu görüyorum! –

+0

@Adrian Adkison - Bu amaç için bir LoadHtml aşırı yükü var. –

2

XML ve XSLT çıktılarını oluşturmalısınız. Bunu yapmak için XML'i indirmeniz gerekiyor ve bunu zaten yaptınız. Sonraki XSL referansını tanımlamak için XML'yi ayrıştırın. Sonra XSL'yi indirmeniz ve bunu XML belgesine uygulamanız gerekir.

Bu bağlantılar İşte

+0

teşekkürler, bunu yapmayı bitirdim, ancak uygulamayı yapmadığı için bunu cevap olarak işaretlemedi. –

0

yararlı olabilir keresinde yanıt aldı kullanarak sona erdi ek kodudur. Bu yanıtın yalnızca "application/xml" ise ve sadece boş nesneler olup olmadığını kontrol etmeniz gerektiğini lütfen unutmayın. Ayrıca, FormAssetSrc, href değerini alan özel bir işlevdir ve protokol, kök veya belge olup olmadığını belirler ve tam olarak nitelenmiş uri oluşturur.

var xmlStream = response.GetResponseStream(); 
var xmlDocument = new XPathDocument(xmlStream); 
var styleNode = xmlDocument.CreateNavigator().SelectSingleNode("processing-instruction('xml-stylesheet')"); 
var hrefValue = Regex.Match((styleNode).Value, "href=(\"|')(?<url>.*?)(\"|')"); 
if(hrefValue.Success) 
{ 
    var xslHref = FormAssetSrc(hrefValue.Groups["url"].Value, response.ResponseUri); 
    var xslUri = new Uri(xslHref); 
    var xslRequest = CreateWebRequest(xslUri); 
    var xslResponse = (HttpWebResponse)xslRequest.GetResponse(); 
    var xslStream = new XPathDocument(xslResponse.GetResponseStream()); 
    var xslTransorm = new XslTransform(); 
    var sw = new System.IO.StringWriter(); 
    xslTransorm.Load(xslStream); 
    xslTransorm.Transform(xmlDocument.CreateNavigator(), null, sw); 
    page.Html.LoadHtml(sw.ToString()); 
} 
+0

CreateWebRequest da –

İlgili konular