এক্সএমএল ডকুমেন্ট থেকে লাইন ব্রেকগুলির সাথে ইন্টেন্টেড এক্সএমএল পাওয়ার সহজ উপায় কী?


105

যখন আমি এক্সএমএলটি স্ক্র্যাচ থেকে শুরু করি XmlDocument, তখন OuterXmlসম্পত্তিটিতে লাইন ব্রেকগুলির সাথে সুন্দরভাবে সমস্ত কিছু থাকে। যাইহোক, আমি যদি LoadXmlকিছু খুব "সংক্ষেপিত" এক্সএমএল (কোনও লাইন ব্রেক বা ইন্ডেনশন না) কল করি তবে আউটপুটটি সেভাবেই OuterXmlথাকে। তাই ...

উদাহরণস্বরূপ থেকে এক্সএমএল আউটপুটটি সুন্দরী করার সহজ উপায় কী XmlDocument?

উত্তর:


209

অন্যান্য উত্তরের উপর ভিত্তি করে, আমি XmlTextWriterনিম্নলিখিত সহায়ক পদ্ধতিটি সন্ধান করেছি এবং এনেছি :

static public string Beautify(this XmlDocument doc)
{
    StringBuilder sb = new StringBuilder();
    XmlWriterSettings settings = new XmlWriterSettings
    {
        Indent = true,
        IndentChars = "  ",
        NewLineChars = "\r\n",
        NewLineHandling = NewLineHandling.Replace
    };
    using (XmlWriter writer = XmlWriter.Create(sb, settings)) {
        doc.Save(writer);
    }
    return sb.ToString();
}

আমি আশা করি এর চেয়ে এটি কিছুটা বেশি কোড তবে এটি কেবল পীচিযুক্ত কাজ করে।


5
আপনি এমনকি আপনার ইউটিলিটি পদ্ধতিটি এক্সএমএল ডকুমেন্ট শ্রেণিতে এক্সটেনশন পদ্ধতি হিসাবে তৈরি করতে বিবেচনা করতে পারেন।
বিরোধী

5
অদ্ভুতভাবে যথেষ্ট, আমার জন্য এটি এক্সএমএল শিরোনামের ইউটিএফ -16 এ এনকোডিং সেট করা ব্যতীত আর কিছুই করে না। আশ্চর্যজনকভাবে যথেষ্ট, এটি আমি স্পষ্টভাবে সেট করে নিলেও এটি করেsettings.Encoding = Encoding.UTF8;
নাইয়ারগডস

3
এনকোডিং সমস্যাটি এর পরিবর্তে নির্দিষ্ট এনকোডিং সহ MemoryStream+ ব্যবহার করে এবং পাঠ্যটি দিয়ে সমাধান করা যেতে পারে । যদিও শেষ ফলাফলটি এখনও কোনওভাবেই বিন্যাসিত নয়। এটি কি সম্পর্কিত হতে পারে যে আমি কোনও পঠন দস্তাবেজ থেকে শুরু করছি যা ইতিমধ্যে ফর্ম্যাটিং আছে? আমি কেবল আমার নতুন নোডগুলিও ফর্ম্যাট করতে চাই। StreamWriterStringBuilderenc.GetString(memstream.GetBuffer(), 0, (int)memstream.Length);
নাইয়ারগডস

2
আমি পরিবর্তন করতে প্রলুব্ধ করছি "\r\n"করার Environment.Newline
ফারাপ

2
doc.PreserveWhitespaceসত্য হিসাবে সেট করা উচিত নয়। অন্যথায় এটি ব্যর্থ হয় যদি এটি ইতিমধ্যে আংশিক অন্তর্ভুক্ত থাকে।
মাস্টার ডি জোন

48

এরিকা এহরলির ব্লগ থেকে যেমন রূপান্তরিত হয়েছে , এটি করা উচিত:

XmlDocument doc = new XmlDocument();
doc.LoadXml("<item><name>wrench</name></item>");
// Save the document to a file and auto-indent the output.
using (XmlTextWriter writer = new XmlTextWriter("data.xml", null)) {
    writer.Formatting = Formatting.Indented;
    doc.Save(writer);
}

10
usingবিবৃতিটির সমাপ্তি যখন Dispose()ডাকা হবে তখন স্বয়ংক্রিয়ভাবে লেখককে বন্ধ করে দেবে ।
টাইলার লি

3
আমার জন্য, এটি কেবল একটি লাইন প্রবেশ করে। আমার কাছে এখনও কয়েক ডজন অন্যান্য লাইন রয়েছে যা ইন্টেন্টেড নয়।
সি জনসন

40

অথবা লিনকের অ্যাক্সেস থাকলে এমনকি আরও সহজ

try
{
    RequestPane.Text = System.Xml.Linq.XElement.Parse(RequestPane.Text).ToString();
}
catch (System.Xml.XmlException xex)
{
            displayException("Problem with formating text in Request Pane: ", xex);
}

খুব সুন্দর! স্বীকৃত উত্তরের উপরের সুবিধাগুলি হ'ল এটি কোনও এক্সএমএল মন্তব্য প্রকাশ করবে না এটি এক্সএমএল খণ্ডের জন্য আরও ভাল কাজ করে
উমর ফারুক খাজা

3
আশ্চর্যের, এই সরিয়ে ফেলা হবে <?xml ...?>এবং <!DOCTYPE ...>XML থেকে। খণ্ডের জন্য ঠিক আছে, তবে একটি পূর্ণ দস্তাবেজের পক্ষে কাম্য নয়।
জেসি চিশম

এটি আমার পক্ষে কাজ করার একমাত্র উপায়। XMLtextwriter, বিন্যাস = ফর্ম্যাটিং ব্যবহার করে অন্যান্য সমস্ত পদ্ধতি ndএন্ডেন্টেড এবং এক্সএমএল রাইটারসেটিংগুলি পাঠ্যের পুনরায় ফর্ম্যাট করে না, তবে এই পদ্ধতিটি করে।
কেএক্স 2 ই

16

একটি সংক্ষিপ্ত সম্প্রসারণ পদ্ধতির সংস্করণ

public static string ToIndentedString( this XmlDocument doc )
{
    var stringWriter = new StringWriter(new StringBuilder());
    var xmlTextWriter = new XmlTextWriter(stringWriter) {Formatting = Formatting.Indented};
    doc.Save( xmlTextWriter );
    return stringWriter.ToString();
}

এটি খুব ভালভাবে কাজ করে এবং ডিস্কে অপ্রয়োজনীয় ফাইল তৈরি করা জড়িত না
জয়ন রিজভি

13

উপরের বিউটিফাই পদ্ধতিটি যদি XmlDocumentইতিমধ্যে একটি XmlProcessingInstructionশিশু নোড ধারণ করে তার জন্য ডাকা হচ্ছে তবে নিম্নলিখিত ব্যতিক্রম নিক্ষেপ করা হবে:

এক্সএমএল ঘোষণা লিখতে পারে না। WritStartDocament পদ্ধতি ইতিমধ্যে এটি লিখে ফেলেছে।

ব্যতিক্রম থেকে মুক্তি পাওয়ার জন্য এটি আমার আসলটির পরিবর্তিত সংস্করণ:

private static string beautify(
    XmlDocument doc)
{
    var sb = new StringBuilder();
    var settings =
        new XmlWriterSettings
            {
                Indent = true,
                IndentChars = @"    ",
                NewLineChars = Environment.NewLine,
                NewLineHandling = NewLineHandling.Replace,
            };

    using (var writer = XmlWriter.Create(sb, settings))
    {
        if (doc.ChildNodes[0] is XmlProcessingInstruction)
        {
            doc.RemoveChild(doc.ChildNodes[0]);
        }

        doc.Save(writer);
        return sb.ToString();
    }
}

এটি এখন আমার জন্য কাজ করে, সম্ভবত আপনাকে XmlProcessingInstructionকেবল প্রথমটি নয়, নোডের জন্য সমস্ত শিশু নোড স্ক্যান করতে হবে?


এপ্রিল 2015 আপডেট করুন:

যেহেতু আমার অন্য একটি এনকোডিং ছিল সেখানে ভুল ছিল, আমি কীভাবে বিওএম ছাড়াই ইউটিএফ -8 প্রয়োগ করতে পারি তা অনুসন্ধান করেছিলাম। আমি এই ব্লগ পোস্টটি খুঁজে পেয়েছি এবং এর ভিত্তিতে একটি ফাংশন তৈরি করেছি:

private static string beautify(string xml)
{
    var doc = new XmlDocument();
    doc.LoadXml(xml);

    var settings = new XmlWriterSettings
    {
        Indent = true,
        IndentChars = "\t",
        NewLineChars = Environment.NewLine,
        NewLineHandling = NewLineHandling.Replace,
        Encoding = new UTF8Encoding(false)
    };

    using (var ms = new MemoryStream())
    using (var writer = XmlWriter.Create(ms, settings))
    {
        doc.Save(writer);
        var xmlString = Encoding.UTF8.GetString(ms.ToArray());
        return xmlString;
    }
}

আপনি প্যারেন্ট নোডের ভিতরে এবং চাইল্ড নোডের আগে সিডিটা বিভাগ রাখলে এটি কাজ করবে না
সাশা বন্ড

2
কমপক্ষে আমার পক্ষে মেমরিস্ট্রিমের প্রয়োজন বলে মনে হচ্ছে না। সেটিংসে আমি সেট করেছি: Encoding = Encoding.UTF8এবংOmitXmlDeclaration = true
মাস্টার ডিজন


5
    public static string FormatXml(string xml)
    {
        try
        {
            var doc = XDocument.Parse(xml);
            return doc.ToString();
        }
        catch (Exception)
        {
            return xml;
        }
    }

নীচের উত্তরটি অবশ্যই কিছু ব্যাখ্যা দিয়ে করতে পারে তবে তা আমার পক্ষে কাজ করেছে এবং অন্যান্য সমাধানের তুলনায় অনেক সহজ।
কার্লআর

PS 3 এ কাজ করার জন্য আপনাকে সিস্টেম.লিংক.এক্সএমএল সমাবেশটি আমদানি করতে হবে বলে মনে হচ্ছে
কার্লআর

2

একটি সহজ উপায় ব্যবহার করা হয়:

writer.WriteRaw(space_char);

এই নমুনা কোডটির মতো, এই কোডটি আমি এক্সএমএল রাইটার ব্যবহার করে কাঠের মতো কাঠের ভিউ তৈরি করতে ব্যবহার করেছি:

private void generateXML(string filename)
        {
            using (XmlWriter writer = XmlWriter.Create(filename))
            {
                writer.WriteStartDocument();
                //new line
                writer.WriteRaw("\n");
                writer.WriteStartElement("treeitems");
                //new line
                writer.WriteRaw("\n");
                foreach (RootItem root in roots)
                {
                    //indent
                    writer.WriteRaw("\t");
                    writer.WriteStartElement("treeitem");
                    writer.WriteAttributeString("name", root.name);
                    writer.WriteAttributeString("uri", root.uri);
                    writer.WriteAttributeString("fontsize", root.fontsize);
                    writer.WriteAttributeString("icon", root.icon);
                    if (root.children.Count != 0)
                    {
                        foreach (ChildItem child in children)
                        {
                            //indent
                            writer.WriteRaw("\t");
                            writer.WriteStartElement("treeitem");
                            writer.WriteAttributeString("name", child.name);
                            writer.WriteAttributeString("uri", child.uri);
                            writer.WriteAttributeString("fontsize", child.fontsize);
                            writer.WriteAttributeString("icon", child.icon);
                            writer.WriteEndElement();
                            //new line
                            writer.WriteRaw("\n");
                        }
                    }
                    writer.WriteEndElement();
                    //new line
                    writer.WriteRaw("\n");
                }

                writer.WriteEndElement();
                writer.WriteEndDocument();

            }

        }

আপনি সাধারণত যেভাবে ব্যবহৃত হয় সেভাবে আপনি ট্যাব বা লাইন ব্রেকগুলি যুক্ত করতে পারেন, যেমন \ t বা \ n


1

এখানে পোস্ট পরামর্শগুলি বাস্তবায়ন করার সময়, পাঠ্য এনকোডিংয়ে আমার সমস্যা হয়েছিল। দেখে মনে হচ্ছে এর এনকোডিং XmlWriterSettingsউপেক্ষা করা হয়েছে এবং সর্বদা স্ট্রিমের এনকোডিং দ্বারা ওভাররাইড করা হয়। একটি ব্যবহার করার সময় StringBuilder, এটি সর্বদা সি # তে অভ্যন্তরীণভাবে ব্যবহৃত টেক্সট এনকোডিং হয়, নাম ইউটিএফ -16।

সুতরাং এখানে এমন একটি সংস্করণ যা অন্যান্য এনকোডিংগুলিকেও সমর্থন করে।

গুরুত্বপূর্ণ দ্রষ্টব্য: ডকুমেন্টটি লোড করার সময় যদি আপনার XMLDocumentঅবজেক্টটির preserveWhitespaceসম্পত্তি সক্রিয় করা থাকে তবে ফর্ম্যাটিংটি সম্পূর্ণ উপেক্ষা করা হবে । এটি আমাকে কিছুক্ষণের জন্য স্টাম্পড করেছিল, সুতরাং এটি সক্ষম না করার বিষয়ে নিশ্চিত হন।

আমার চূড়ান্ত কোড:

public static void SaveFormattedXml(XmlDocument doc, String outputPath, Encoding encoding)
{
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = true;
    settings.IndentChars = "\t";
    settings.NewLineChars = "\r\n";
    settings.NewLineHandling = NewLineHandling.Replace;

    using (MemoryStream memstream = new MemoryStream())
    using (StreamWriter sr = new StreamWriter(memstream, encoding))
    using (XmlWriter writer = XmlWriter.Create(sr, settings))
    using (FileStream fileWriter = new FileStream(outputPath, FileMode.Create))
    {
        if (doc.ChildNodes.Count > 0 && doc.ChildNodes[0] is XmlProcessingInstruction)
            doc.RemoveChild(doc.ChildNodes[0]);
        // save xml to XmlWriter made on encoding-specified text writer
        doc.Save(writer);
        // Flush the streams (not sure if this is really needed for pure mem operations)
        writer.Flush();
        // Write the underlying stream of the XmlWriter to file.
        fileWriter.Write(memstream.GetBuffer(), 0, (Int32)memstream.Length);
    }
}

এটি প্রদত্ত পাঠ্য এনকোডিং সহ ডিস্কে ফর্ম্যাট xML সংরক্ষণ করবে।


1

যদি আপনার কাছে XML- র স্ট্রিং থাকে তবে ডকুমেন্ট ব্যবহারের জন্য প্রস্তুত না হয়ে আপনি এইভাবে এটি করতে পারেন:

var xmlString = "<xml>...</xml>"; // Your original XML string that needs indenting.
xmlString = this.PrettifyXml(xmlString);

private string PrettifyXml(string xmlString)
{
    var prettyXmlString = new StringBuilder();

    var xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(xmlString);

    var xmlSettings = new XmlWriterSettings()
    {
        Indent = true,
        IndentChars = " ",
        NewLineChars = "\r\n",
        NewLineHandling = NewLineHandling.Replace
    };

    using (XmlWriter writer = XmlWriter.Create(prettyXmlString, xmlSettings))
    {
        xmlDoc.Save(writer);
    }

    return prettyXmlString.ToString();
}

1

গৃহীত উত্তরের উপর ভিত্তি করে আরও সরল পদ্ধতি:

static public string Beautify(this XmlDocument doc) {
    StringBuilder sb = new StringBuilder();
    XmlWriterSettings settings = new XmlWriterSettings
    {
        Indent = true
    };

    using (XmlWriter writer = XmlWriter.Create(sb, settings)) {
        doc.Save(writer);
    }

    return sb.ToString(); 
}

নতুন লাইন স্থাপন প্রয়োজনীয় নয়। ইনডেন্ট অক্ষরগুলির ডিফল্ট দুটি স্পেসও রয়েছে তাই আমি এটি সেট না করাও পছন্দ করি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.