Skip to content

XmlMarkupFormatter and self-closing tags #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
duncanawoods opened this issue Sep 13, 2019 · 6 comments
Closed

XmlMarkupFormatter and self-closing tags #11

duncanawoods opened this issue Sep 13, 2019 · 6 comments
Labels
bug Something isn't working enhancement New feature or request help wanted Extra attention is needed
Milestone

Comments

@duncanawoods
Copy link

duncanawoods commented Sep 13, 2019

I can't see a way to choose self-closing tags.

The default format of many partially-human readable xml files e.g. csproj files, is to use self-closing tags. If you round trip a file through XmlMarkupFormatter then they will become uglified.

I would appreciate an option to choose self-closing but ideally I would support changing the default to be self-closing because it produces shorter and more readable output and I have no use-case for the verbose form.

Here is my current work-around to wrap the XmlMarkupFormatter:

public class SelfClosingXmlMarkupFormatter : IMarkupFormatter
{
    public string Text(ICharacterData text) =>
        XmlMarkupFormatter.Instance.Text(text);

    public string Comment(IComment comment) =>
        XmlMarkupFormatter.Instance.Comment(comment);

    public string Processing(IProcessingInstruction processing) =>
        XmlMarkupFormatter.Instance.Processing(processing);

    public string Doctype(IDocumentType doctype) =>
        XmlMarkupFormatter.Instance.Doctype(doctype);

    public string OpenTag(IElement element, bool selfClosing) =>
        XmlMarkupFormatter.Instance.OpenTag(element, !(element.HasChildNodes || element.HasTextNodes()));

    public string CloseTag(IElement element, bool selfClosing) =>
        XmlMarkupFormatter.Instance.CloseTag(element, !(element.HasChildNodes || element.HasTextNodes()));

    public string Attribute(IAttr attribute) =>
        XmlMarkupFormatter.Instance.Attribute(attribute);
}
@duncanawoods duncanawoods added the enhancement New feature or request label Sep 13, 2019
@FlorianRappl
Copy link
Contributor

Sounds good.

Can you share an example how you produced the original format - which is not round-trip preserved? Thanks!

@FlorianRappl FlorianRappl added the help wanted Extra attention is needed label Sep 24, 2019
@FlorianRappl FlorianRappl added this to the v0.14 milestone Sep 24, 2019
@duncanawoods
Copy link
Author

Here you go. Ideally it wouldn't be ToHtml but I understand the naming difficulty across different markup formats. You nicely solve it in the library name AngleSharp... so maybe ToAngles?! Ok maybe not... ToText, ToFormat, ToMarkup would work.

[Test]
public void test_xml()
{
    var xmlDoc = new XmlParser().ParseDocument(
        @"<Project Sdk=""Microsoft.NET.Sdk"">
            <ItemGroup>
                <PackageReference Include=""AngleSharp"" Version=""0.12.1"" />
                <PackageReference Include=""AngleSharp.Xml"" Version=""0.12.1"" />
                <PackageReference Include=""AngleSharp.XPath"" Version=""1.1.4"" />
            </ItemGroup>   
        </Project>");

    {
        var sw = new StringWriter();
        xmlDoc.ToHtml(sw, new XmlMarkupFormatter());
        
        Console.WriteLine("BOO");
        Console.WriteLine(sw.ToString());
        Console.WriteLine();
    }
    
    {
        var sw = new StringWriter();
        xmlDoc.ToHtml(sw, new SelfClosingXmlMarkupFormatter());
        
        Console.WriteLine("YAY");
        Console.WriteLine(sw.ToString());
        Console.WriteLine();
    }
}

@FlorianRappl
Copy link
Contributor

I mean the most ideal would be ToString (and I think it was our original design choice), but it comes with some drawbacks (most notably the debug experience - despite some attributes that can then help out / alleviate the situation a bit).

Independent of the name - thanks for the example; I'll look into it!

@duncanawoods
Copy link
Author

Yep, I've experienced the same drawbacks. They should call it ToDebugSummary given it's now so intimately tied into to debuggers/IDEs. My default is ToText for non-trivial string generation which I would otherwise call ToString.

@FlorianRappl FlorianRappl added the bug Something isn't working label Sep 26, 2019
@FlorianRappl
Copy link
Contributor

Part of it landed in devel. Notably:

  • You can know configure the XmlMarkupFormatter with an option called IsAlwaysSelfClosing. Setting this property to true will serialize empty elements as self-closing.

What we miss so far is that an element that was declared as self-closing should be serialized as self-closing. For this, however, we require AngleSharp 0.14 - with a breaking change regarding the element construction from documents (allowing to set the respective NodeFlags).

@FlorianRappl
Copy link
Contributor

Fully landed in devel using AngleSharp v0.14 preview.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants