2010-11-30 30 views
5

का उपयोग कर मैं एक एचटीएमएल वेब XSLT का उपयोग कर पृष्ठ की सामग्री को बदलने के लिए की जरूरत XSL रूपांतरण प्रदर्शन करने के लिए। इसलिए मैं SgmlReader का इस्तेमाल किया और लिखा टुकड़ा नीचे दिखाया गया है (मैं सोचा, अंत में, यह एक XmlReader भी है ...)सी # - यह संभव (और कैसे) है SgmlReader

XmlReader xslr = XmlReader.Create(new StringReader(
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + 
    "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" + 
    "<xsl:output method=\"xml\" encoding=\"UTF-8\" version=\"1.0\" />" + 
    "<xsl:template match=\"/\">" + 
    "<XXX xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><xsl:value-of select=\"count(//br)\" /></XXX>" + 
    "</xsl:template>" + 
    "</xsl:stylesheet>")); 

XslCompiledTransform xslt = new XslCompiledTransform(); 
xslt.Load(xslr); 

using (SgmlReader html = new SgmlReader()) 
{ 
    StringBuilder sb = new StringBuilder(); 
    using (TextWriter sw = new StringWriter(sb)) 
    using (XmlWriter xw = new XmlTextWriter(sw)) 
    { 
     html.InputStream = new StringReader(Resources.html_orig); 
     html.DocType = "HTML"; 

     try 
     { 
      xslt.Transform(html, xw); 
      string output = sb.ToString(); 
      System.Console.WriteLine(output); 
     } 
     catch (Exception exc) 
     { 
      System.Console.WriteLine("{0} : {1}", exc.GetType().Name, exc.Message); 
      System.Console.WriteLine(exc.StackTrace); 
     } 
    } 
} 

बहरहाल, मैं thos त्रुटि संदेश मिलता है

NullReferenceException : Object reference not set to an instance of an object. 
    at MS.Internal.Xml.Cache.XPathDocumentBuilder.Initialize(XPathDocument doc, IXmlLineInfo lineInfo, String baseUri, LoadFlags flags) 
    at MS.Internal.Xml.Cache.XPathDocumentBuilder..ctor(XPathDocument doc, IXmlLineInfo lineInfo, String baseUri, LoadFlags flags) 
    at System.Xml.XPath.XPathDocument.LoadFromReader(XmlReader reader, XmlSpace space) 
    at System.Xml.XPath.XPathDocument..ctor(XmlReader reader, XmlSpace space) 
    at System.Xml.Xsl.Runtime.XmlQueryContext.ConstructDocument(Object dataSource, String uriRelative, Uri uriResolved) 
    at System.Xml.Xsl.Runtime.XmlQueryContext..ctor(XmlQueryRuntime runtime, Object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, WhitespaceRuleLookup wsRules) 
    at System.Xml.Xsl.Runtime.XmlQueryRuntime..ctor(XmlQueryStaticData data, Object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, XmlSequenceWriter seqWrt) 
    at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results) 
    at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter) 
    at System.Xml.Xsl.XmlILCommand.Execute(XmlReader contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results) 
    at System.Xml.Xsl.XslCompiledTransform.Transform(XmlReader input, XmlWriter results) 

मुझे एचटीएमएल से एक्सएमएल और फिर ट्रांसफॉर्म को लागू करके इस पर काम करने का एक तरीका मिला, लेकिन यह एक अक्षम समाधान है क्योंकि:

  1. मध्यवर्ती एक्सएचटीएमएल उत्पादन एक बफर के लिए चला जाता है, तो अतिरिक्त स्मृति की जरूरत है
  2. रूपांतरण प्रक्रिया अतिरिक्त सीपीयू प्रसंस्करण की जरूरत है और एक ही पदानुक्रम में दो बार (सिद्धांत में अनावश्यक रूप से) चल रहा है।

तो (के बाद से मैं जानता हूँ कि StackOverflow समुदाय हमेशा जबकि महान उत्तर प्रदान करता है अन्य सी # मंचों पूरी तरह से मुझे निराश किया है ; ओ) मैं इतनी के रूप में XSL प्रदर्शन करने के लिए प्रतिक्रिया और सुझाव की तलाश में हो जाएगाएचटीएमएल का उपयोग कर परिवर्तन (भले ही एसजीएमएल रीडर को एक और इसी तरह की लाइब्रेरी द्वारा प्रतिस्थापित करने की आवश्यकता है)।

एक अग्रिम

+1

अंडरलाइन प्रश्न के बारे में: एक्सएसएलटी 1.0 एक्सएमएल इनपुट पेड़ के साथ काम करता है (एक्सएसएलटी 2.0 अनपेक्षित संसाधनों का उपयोग कर सकता है)।यदि आपके पास कुछ ऐसा है जो यह एक एक्सएमएल पेड़ नहीं है, तो आपको इसे XML पेड़ पर मैप करने के लिए कुछ विधि का उपयोग करने की आवश्यकता है। –

+1

ओलेमिस, बस एक नोट, XslCompiledTransform एक एक्सएसएलटी 1.0 प्रोसेसर है, इस प्रकार यदि आप अपनी स्टाइलशीट में संस्करण = "2.0" का उपयोग करते हैं तो यह आगे संगत मोड में चलता है और आपको सभी एक्सएसएलटी 1.0 सिंटैक्स त्रुटियों की रिपोर्ट नहीं मिल जाएगी। तो मैं आपकी स्टाइलशीट में संस्करण = "1.0" सेट करना शुरू कर दूंगा क्योंकि XslCompiledTransform आपको पहले से ही लोड कॉल पर सूचित करेगा कि आपकी स्टाइलशीट xsl के रूप में वाक्यगत रूप से गलत है: xsl के अंदर आउटपुट: टेम्पलेट की अनुमति नहीं है। चाहे वह SgmlReader को खिलाने पर आपकी समस्या में मदद करता है, मुझे यकीन नहीं है, आपको एक नमूना HTML प्रदान करना होगा जिसका उपयोग आप कर रहे हैं जो अपवाद देता है। –

उत्तर

1

धन्यवाद आप SgmlReader के बजाय HTML Agility Pack उपयोग करने की कोशिश की है? आप इसमें एचटीएमएल लोड कर सकते हैं, और सीधे इसके खिलाफ एक ट्रांसफॉर्म चला सकते हैं। यदि कोई एक्सएमएल दस्तावेज़ आंतरिक रूप से बनाया गया है, तो मैं सकारात्मक नहीं हूं, हालांकि - ऐसा लगता है कि कोई ऐसा नहीं है कि आप संभवतः उस मेमोरी और सीपीयू उपयोग की तुलना करना चाहते हैं जिसकी आपने कोशिश की और त्याग दिया।

//You already have your xslt loaded into var xslt... 

HtmlDocument doc = new HtmlDocument(); 
doc.Load(...); //load your HTML doc, or use LoadXML from a string, etc 
xslt.Transform(doc, xw); 

भी इस सवाल देखें: How to use HTML Agility pack

+0

आपके उत्तर के लिए धन्यवाद फिलिप, लेकिन * एचटीएमएल डोम * का निर्माण समय लेने वाला हो सकता है और अतिरिक्त मेमोरी भी उपयोग की जाएगी। मैं वास्तव में स्मृति और अतिरिक्त प्रसंस्करण में वस्तुओं को लोड करने से बचना चाहता हूं क्योंकि अनुप्रयोग सीमित क्षमताओं वाले उपकरणों पर चलना चाहिए। यही कारण है कि मैं * एचटीएमएल * * एक्सएमएल रीडर * को * एक्सएसएलटी * पर सीधे फ़ीड करने का तरीका ढूंढ रहा था (लेकिन, ट्रेसबैक पर विचार करते हुए, ऐसा लगता है कि यह एक * System.Xml.XPath.XPathDocument * आंतरिक रूप से बनाता है, तो हो सकता है कि मैं कोई अनुकूलन कर सकूं इमेजिंग सिर्फ समय की बर्बादी है ...) –

2

यहां तक ​​कि अगर SgmlReader वर्ग XmlReader वर्ग प्रदान कर रहा है इसका मतलब यह नहीं है कि यह भी बर्ताव एक XmlReader की तरह।

तकनीकी रूप से यह भी समझ में नहीं आता है कि SgmlReaderXmlReader का उप-वर्ग है, क्योंकि केवल एसजीएमएल एक्सएमएल का सुपरसेट है और सबसेट नहीं है।

आप अपने परिवर्तन के उद्देश्य के बारे में लिखने नहीं था, लेकिन सामान्य रूप में HTML Agility Pack एचटीएमएल जोड़ तोड़ के लिए एक अच्छा विकल्प है।

+0

सभी सम्मान के साथ ** वास्तव में ** वास्तव में समझता है (कम से कम * ओओपी * परिप्रेक्ष्य से) तथ्य यह है कि * एक्सएमएल रीडर * एक प्रकार है, इस इंटरफेस को लागू करने वाला कुछ भी हो सकता है छेड़छाड़ की जा सकती है (इस मामले में पढ़ा गया है) ** जैसे कि यह ** एक * एक्सएमएल * दस्तावेज़ था। दरअसल यह * संरचित प्रारूपों जैसे * वाईएएमएल *, * आईएनआई * फाइलों के लिए * एक्सएमएल रीडर * एस को कार्यान्वित करने के लिए समझ में आता है ... भले ही वे बिल्कुल मार्कअप न हों, वे संरचित दस्तावेज हैं जिन्हें आप एक संरचित में पढ़ना और बदलना चाहते हैं मार्ग। एकदम मेरे विचार। –

+0

@ ओलेमिस लैंग: मेरी राय में यह समझ में नहीं आता है क्योंकि XmlReader एक अच्छी तरह से गठित दस्तावेज़ की अपेक्षा करता है, यानी एक पेड़ संरचना वाला दस्तावेज़। एसजीएमएल इसके लिए उपलब्ध नहीं कराता है, इसलिए 'रीडसब्रीटी' या 'रीडइनरएक्सएमएल' जैसी विधियां कोई समझ नहीं लेती हैं। तो एक एसजीएमएल रीडर पर एक्सएसएलटी चलाने के मामले में आप वास्तव में इस मामले में भाग ले सकते हैं कि अंतर्निहित इंजन इन विधियों में से एक को कॉल करता है लेकिन यह अपेक्षा करता है कि वह क्या अपेक्षा करता है। XSLT द्वारा अपेक्षित अपेक्षाओं पर अलेजैंड्रो की टिप्पणी भी देखें। –

+0

और @Alejandro: मैंने सोचा था कि * SgmlReader * के लिए था (यानी विकृत HTML का इलाज करें जैसे कि यह * एक्सएचटीएमएल * समकक्ष था, यह सब * HTML * के विशिष्ट मामले में)। वास्तव में यदि आप ट्रेसबैक पर एक नज़र डालते हैं तो ऐसा लगता है कि पाठक का उपयोग * System.Xml.XPath.XPathDocument * का एक उदाहरण बनाने के लिए किया जाता है, जिसे संकलित * एक्सएसएल * अंडर-द-हूड में परिवर्तित किया जाता है। वैसे भी मैं कुछ तरीकों से यह सुनिश्चित करने के लिए कोशिश करूंगा कि * ReadSubtree * et al के साथ क्या होता है। धन्यवाद –

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