2011-03-21 6 views
5

मैं एक XML फ़ाइल पढ़ने के लिए HtmlAgilityPack के लिए सबसे अच्छा तरीका सोच रहा था जिसमें HTML प्रस्तुत करने के लिए एक xsl फ़ाइल शामिल है। क्या HtmlDocument क्लास पर कोई सेटिंग है जो इसमें सहायता करेगी, या क्या मुझे HtmlAgiliyPack से लोड करने से पहले रूपांतरण निष्पादित करने का कोई तरीका ढूंढना है? यदि हां बाद के लिए, किसी को भी एक अच्छी पुस्तकालय या इस तरह के परिवर्तन के लिए विधि के बारे में पता है? नीचे एक ऐसी वेबसाइट का एक उदाहरण है जो एक्सएलएल फ़ाइल और एक्स कोड के साथ एक्सएमएल लौटाता है जिसे मैं उपयोग करना चाहता हूं।क्या HtmlAgilityPack एक XML फ़ाइल को संभाल सकता है जो HTML को प्रस्तुत करने के लिए xsl फ़ाइल के साथ आता है?

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

इस कोड को किसी भी त्रुटि फेंक नहीं है, लेकिन एक्सएमएल क्या पार्स हो जाता है और नहीं परिवर्तन है, जो मैं चाहता है।

+2

आप अच्छी तरह से गठित किया है, तो एक्सएमएल, क्यों बिल्कुल HtmlAgilityPack का उपयोग करें? – Cameron

+0

मैं पृष्ठ सारांश, यानी पृष्ठ शीर्षक, और मेटा विवरण, और पृष्ठ पर आईएमजी srcs की एक सूची प्राप्त करने का प्रयास कर रहा हूं। मैं वेब से किसी भी वैध यूआरएल के इनपुट की इजाजत दे रहा हूं। तो अपने प्रश्न का उत्तर देने के लिए, मेरे पास हमेशा अच्छी तरह से गठित xml नहीं होता है और यहां तक ​​कि यदि मैंने किया, तो दस्तावेज़ शीर्षक और विवरण असंगत रूप से स्वरूपित किया जाएगा। –

उत्तर

3

एचटीएमएल चपलता पैक दो अंक पर यहाँ आप मदद कर सकते हैं:

1) यह इसके साथ एक Xml प्रोसेसिंग निर्देश प्राप्त करने के लिए के रूप में यह HTML के रूप में पीआई डेटा पार्स आसान है, तो यह गुण में बदलने जाएगा

2) एचटीएमएल दस्तावेज़ IXPathNavigable लागू करता है ताकि इसे सीधे .NET Xslt रूपांतरण इंजन द्वारा बदला जा सके।

यहां कोड का एक टुकड़ा है जो काम करता है। Xslt को ठीक तरह से बदलने के लिए मुझे एक विशिष्ट XmlResover जोड़ना पड़ा, लेकिन मुझे लगता है कि यह इस skechers मामले के लिए विशिष्ट है।

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

और आप इसे इस तरह कहते हैं:

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

के पहले कोड स्निपेट में अनुरोध करता है, धन्यवाद, मुझे लगता है कि मेरे उद्देश्यों के लिए, मेरे पास जो कोड है वह थोड़ा बेहतर काम करेगा। मुझे लगता है कि यह कैसे करेगा मैं एक सामान्य गाइड के लिए यह आपके कोड की सिफारिश करेंगे। बीटीडब्ल्यू, एचटीएमएलएगिलिटीपैक एफ * #% कमाल है। –

+0

मैं यह भी जोड़ना चाहूंगा कि स्ट्रीम को मैन्युअल रूप से बनाने के बजाय HtmlDocument.Load विधि में एक HTML स्ट्रिंग में पास करने में सक्षम होना अच्छा होगा।मुझे लगता है कि यह पहले से ही 12 अधिभार की तरह है! –

+0

@ एड्रियन एडकिसन - इस उद्देश्य के लिए एक लोड एचटीएमएल अधिभार है। –

2

आपको एक्सएमएल और एक्सएसएलटी के आउटपुट को प्रस्तुत करना चाहिए। ऐसा करने के लिए आपको एक्सएमएल डाउनलोड करने की जरूरत है, और आप इसे पहले ही कर चुके हैं। एक्सएसएल संदर्भ की पहचान करने के लिए एक्सएमएल को आगे पार्स करें। फिर आपको एक्सएसएल डाउनलोड करने और एक्सएमएल दस्तावेज़ पर लागू करने की आवश्यकता है।

ये लिंक यहाँ उपयोगी

+0

धन्यवाद, मैंने ऐसा करने का अंत किया, लेकिन इसे उत्तर के रूप में चिह्नित नहीं किया क्योंकि इसमें कार्यान्वयन नहीं है। –

0

हो सकता है अतिरिक्त कोड मैं का उपयोग कर एक बार मैं प्रतिक्रिया मिली समाप्त हो गया है। कृपया ध्यान दें कि प्रतिक्रिया केवल "एप्लिकेशन/एक्सएमएल" है, और आपको ऑब्जेक्ट्स के निरर्थक उदाहरणों की जांच करनी होगी। साथ ही, FormAssetSrc एक निजी फ़ंक्शन है जो href का मान लेता है और यह निर्धारित करता है कि यह प्रोटोकॉल, रूट या दस्तावेज़ रिश्तेदार है या पूरी तरह से योग्य यूरी बनाता है।

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 भी एक निजी फ़ंक्शन है जो मूल प्रश्न –

संबंधित मुद्दे