2017-03-22 7 views
6

इससे पहले कि मैं लोगों द्वारा कूदने से पहले कहूं कि एक्सएमएल पार्सर को परवाह नहीं है कि तत्व खाली हैं या स्वयं बंद हैं, इसलिए एक कारण है कि मैं स्वयं बंद एक्सएमएल तत्वों को अनुमति नहीं दे सकता। कारण यह है कि मैं वास्तव में एसजीएमएल के साथ काम नहीं कर रहा हूं एक्सएमएल और एसजीएमएल डीटीडी जो मैं काम कर रहा हूं वह बहुत सख्त है और इसे अनुमति नहीं देता है।सी # में XmlDocument का उपयोग करके मैं खाली XML तत्वों को स्वयं बंद कर सकता हूं?

मैं क्या है कई हजार SGML फ़ाइलें जो मैं पर XSLT चलाने के लिए आवश्यक है। इसलिए मुझे एक्सएसएलटी लागू करने के लिए अस्थायी रूप से एसजीएमएल को एक्सएमएल में परिवर्तित करना पड़ा। मैंने फिर एक विधि लिखी है जो उन्हें वापस एसजीएमएल में परिवर्तित कर देती है (अनिवार्य रूप से केवल एसजीएमएल घोषणा के साथ एक्सएमएल घोषणा को बदलना और ग्राफिक इकाइयों जैसे किसी भी अन्य इकाई घोषणाओं को वापस लिखना)।

मेरे समस्या यह है कि इस रूपांतरण वापस SGML, के बाद जब मैं अपने SGML संपादक में फ़ाइलों को खोलने, फ़ाइलों को पार्स नहीं है के रूप में खाली तत्वों स्वयं बंद कर दिया गया है है।

किसी को भी पता है कि कैसे मैं हो रहा रोक सकता है जब XmlDocument का उपयोग कर कृपया?

तरीकों कि एक्सएमएल SGML को बदलने और फिर से वापस करने के लिए यह एक उपयुक्त XmlWriter उपवर्ग और WriteEndElement() ओवरराइड WriteFullEndElement() कॉल करने के लिए किया जाएगा नीचे

//converts the SGML file to XML – it’s during this conversion that the 
//empty elements get self-closed, i think 

private XmlDocument convertToXML(TextReader reader) 
     { 
      // setup SgmlReader 
      Sgml.SgmlReader sgmlReader = new Sgml.SgmlReader(); 
      //sgmlReader.DocType = "HTML"; 
      sgmlReader.WhitespaceHandling = WhitespaceHandling.All; 
      sgmlReader.CaseFolding = Sgml.CaseFolding.ToLower; 
      sgmlReader.InputStream = reader; 


      // create document 
      XmlDocument doc = new XmlDocument(); 
      doc.PreserveWhitespace = true; 

      doc.XmlResolver = null; 
      doc.Load(sgmlReader); 
      return doc; 
     } 

// method to apply the XSLT stylesheet to the XML document 

private void filterApplic(string applicFilter) 
     { 
      string stylesheet = getRequiredStylesheet(); // do this just once 

      if (stylesheet != "") 
      { 
       foreach (string file in FilesToConvert) 
       { 
        fileName = Path.GetFileName(file); //gets just the file name from the path 
        fileNameNoExt = Path.GetFileNameWithoutExtension(file); 
        string ext = Path.GetExtension(file); 

        if (ext == ".sgm") 
        { 
         try 
         { 
          publicIdentifier = getDoctype(file); // gets the sgml declaration 
          entitiesList = getEntitites(file); // gets the list of entities 

          TextReader tr = new StreamReader(file); 
          myDoc = convertToXML(tr); 

          myDoc.Save(outputFolder + "\\temp.xml"); 

          var myXslTrans = new XslCompiledTransform(); 

          myXslTrans.Load(stylesheet); 
          myXslTrans.Transform(outputFolder + "\\temp.xml", Path.Combine(outputFolder, fileNameNoExt +".xml")); 

          XmlDocument convertedDoc = new XmlDocument(); 
          convertedDoc.Load(Path.Combine(outputFolder, fileNameNoExt + ".xml")); 

          convertToSGM(convertedDoc); 

          filesTransformed++; 
         } 
         catch (Exception e) 
         { 
          MessageBox.Show(e.ToString()); 
         } 

        } 
       } 
      } 
      else 
      { 
       MessageBox.Show("The stylesheet was retured empty. Cannot perform Applicability filter."); 
       return; 
      } 


      MessageBox.Show("Complete! " + filesTransformed.ToString() + " files filtered for " + applicFilter); 
     } 


//convert files back to SGML 
private void convertToSGM(XmlDocument myDoc) 
     { 

      using (var stringWriter = new StringWriter()) 
      using (var xmlTextWriter = XmlWriter.Create(stringWriter, settings)) 
      { 

       myDoc.WriteTo(xmlTextWriter); 
       xmlTextWriter.Flush(); 


       string xmltext = stringWriter.GetStringBuilder().ToString(); 

       xmltext = xmltext.Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "<!DOCTYPE DMODULE " + publicIdentifier + ">"); 
       xmltext = xmltext.Replace("<?xml version=\"1.0\" encoding=\"utf-8\"?>", "<!DOCTYPE DMODULE " + publicIdentifier + ">"); 

       if (entitiesList.Count != 0) 
       { 
        string entityListAsOne = ""; 

        foreach (string entity in entitiesList) 
        { 
         entityListAsOne = entityListAsOne + "\r\n" + entity; 
        } 

        xmltext = xmltext.Replace("//EN\">", "//EN\" [" + entityListAsOne + "]>"); 
       } 

       File.WriteAllText(Path.Combine(outputFolder, fileNameNoExt + ".sgm"), xmltext); 
      } 


     } 

उत्तर

2

एक तरह से दिखाए जाते हैं। यह पसंद का उपयोग

public class FullElementXmlTextWriter : XmlTextWriter 
{ 
    public FullElementXmlTextWriter(TextWriter w) : base(w) { } 

    public FullElementXmlTextWriter(Stream w, Encoding encoding) : base(w, encoding) { } 

    public FullElementXmlTextWriter(string filename, Encoding encoding) : base(filename, encoding) { } 

    public override void WriteEndElement() 
    { 
     base.WriteFullEndElement(); 
    } 
} 

तब:

उदाहरण के लिए, यहाँ है कि काम करता है XmlTextWriter के subclassed संस्करण है

string xmltext; 
using (var stringWriter = new StringWriter()) 
{ 
    using (var xmlTextWriter = new FullElementXmlTextWriter(stringWriter)) 
    { 
     myDoc.WriteTo(xmlTextWriter); 
    } 
    xmltext = stringWriter.ToString(); 
} 

या, आप XmlWriterSettings द्वारा प्रदान नियंत्रण की आवश्यकता है, आप कर सकते हैं

+०१२३५१६४१०६१: एक डेकोरेटर कि स्वचालित रूप से WriteEndElement() से WriteFullEndElement() के लिए कॉल remaps में किसी भी XmlWriter संपुटित करने डेकोरेटर पैटर्न का उपयोग
public class FullElementXmlWriterDecorator : XmlWriterDecorator 
{ 
    public FullElementXmlWriterDecorator(XmlWriter baseWriter) : base(baseWriter) { } 

    public override void WriteEndElement() 
    { 
     base.WriteFullEndElement(); 
    } 
} 

public class XmlWriterDecorator : XmlWriter 
{ 
    readonly XmlWriter baseWriter; 

    public XmlWriterDecorator(XmlWriter baseWriter) 
    { 
     if (baseWriter == null) 
      throw new ArgumentNullException(); 
     this.baseWriter = baseWriter; 
    } 

    protected virtual bool IsSuspended { get { return false; } } 

    public override void Close() 
    { 
     baseWriter.Close(); 
    } 

    public override void Flush() 
    { 
     baseWriter.Flush(); 
    } 

    public override string LookupPrefix(string ns) 
    { 
     return baseWriter.LookupPrefix(ns); 
    } 

    public override void WriteBase64(byte[] buffer, int index, int count) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteBase64(buffer, index, count); 
    } 

    public override void WriteCData(string text) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteCData(text); 
    } 

    public override void WriteCharEntity(char ch) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteCharEntity(ch); 
    } 

    public override void WriteChars(char[] buffer, int index, int count) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteChars(buffer, index, count); 
    } 

    public override void WriteComment(string text) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteComment(text); 
    } 

    public override void WriteDocType(string name, string pubid, string sysid, string subset) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteDocType(name, pubid, sysid, subset); 
    } 

    public override void WriteEndAttribute() 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteEndAttribute(); 
    } 

    public override void WriteEndDocument() 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteEndDocument(); 
    } 

    public override void WriteEndElement() 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteEndElement(); 
    } 

    public override void WriteEntityRef(string name) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteEntityRef(name); 
    } 

    public override void WriteFullEndElement() 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteFullEndElement(); 
    } 

    public override void WriteProcessingInstruction(string name, string text) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteProcessingInstruction(name, text); 
    } 

    public override void WriteRaw(string data) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteRaw(data); 
    } 

    public override void WriteRaw(char[] buffer, int index, int count) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteRaw(buffer, index, count); 
    } 

    public override void WriteStartAttribute(string prefix, string localName, string ns) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteStartAttribute(prefix, localName, ns); 
    } 

    public override void WriteStartDocument(bool standalone) 
    { 
     baseWriter.WriteStartDocument(standalone); 
    } 

    public override void WriteStartDocument() 
    { 
     baseWriter.WriteStartDocument(); 
    } 

    public override void WriteStartElement(string prefix, string localName, string ns) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteStartElement(prefix, localName, ns); 
    } 

    public override WriteState WriteState 
    { 
     get { return baseWriter.WriteState; } 
    } 

    public override void WriteString(string text) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteString(text); 
    } 

    public override void WriteSurrogateCharEntity(char lowChar, char highChar) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteSurrogateCharEntity(lowChar, highChar); 
    } 

    public override void WriteWhitespace(string ws) 
    { 
     if (IsSuspended) 
      return; 
     baseWriter.WriteWhitespace(ws); 
    } 
} 

आप async लेखन कर रहे थे, तो मेरा मानना ​​है कि (लेकिन परीक्षण नहीं किया) है कि आप के रूप में अच्छी async तरीकों को सजाने के लिए चाहते हैं।

string xmltext; 
using (var stringWriter = new StringWriter()) 
{ 
    using (var innerXmlWriter = XmlWriter.Create(stringWriter, settings)) 
    using (var xmlTextWriter = new FullElementXmlWriterDecorator(innerXmlWriter)) 
    { 
     myDoc.WriteTo(xmlTextWriter); 
    } 
    xmltext = stringWriter.ToString(); 
} 

fiddle:

तो यह चाहते का उपयोग करें।

+0

उत्कृष्ट और व्यापक उत्तर। आपका बहुत बहुत धन्यवाद। उत्तम। –

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

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