Skip to content
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

How to control reference naming and remove namespaces? #385

Closed
jamesquox opened this issue Apr 3, 2020 · 6 comments
Closed

How to control reference naming and remove namespaces? #385

jamesquox opened this issue Apr 3, 2020 · 6 comments
Assignees
Labels
question Further information is requested

Comments

@jamesquox
Copy link

First of all a thank you for spending your time to create this masterpiece.
I have two questions/issues that I can't wrap my head around and hopefully you can tell me that it can't be done and I can move on =)

  1. I've tried many ways to get access to the naming used for the identity and reference attributes, but don't see a way of overriding them?
  2. I'm only serialising my model and would like to remove all namespace information.

At the moment I'm performing a regex replace to alter the output xml, but hoped I could do something to ease this.

public string ShapeXml(string xml)
{
    return xml.ReplaceMultiple(new Dictionary<string, string>
    {
        {@"((?<=<|<\/| ))\w+:| xmlns(:\w+)?=\"".*?\""", @"" },
        {@"<Capacity>\d+<\/Capacity>", @"" },
        {@" exs:member=""""", "" },
        {@" exs:identity=""", @" id=""" },
        {@" exs:reference=""", @" ref=""" },
    });
}

I've set up a dotnetfiddle here.

The current output:

<?xml version="1.0" encoding="utf-8"?>
<List xmlns:ns1="clr-namespace:XmlRef.Tests;assembly=Odin.Tests" 
    xmlns:exs="https://extendedxmlserializer.github.io/v2" exs:arguments="XmlRefTests-Person" 
    xmlns="https://extendedxmlserializer.github.io/system">
    <Capacity>4</Capacity>
    <XmlRefTests-Person>
        <Name>Princess Eugenie</Name>
        <Uncles>
            <Capacity>4</Capacity>
            <XmlRefTests-Person exs:identity="2">
                <Name>Price Charles</Name>
            </XmlRefTests-Person>
            <XmlRefTests-Person exs:identity="3">
                <Name>Price Andrew</Name>
            </XmlRefTests-Person>
            <XmlRefTests-Person exs:identity="4">
                <Name>Price Edward</Name>
            </XmlRefTests-Person>
        </Uncles>
        <Aunts>
            <Capacity>4</Capacity>
            <XmlRefTests-Person exs:identity="1">
                <Name>Princess Anne</Name>
            </XmlRefTests-Person>
        </Aunts>
    </XmlRefTests-Person>
    <XmlRefTests-Person>
        <Name>Princess Beatrice</Name>
        <Uncles>
            <Capacity>3</Capacity>
            <XmlRefTests-Person exs:reference="2" />
            <XmlRefTests-Person exs:reference="3" />
            <XmlRefTests-Person exs:reference="4" />
        </Uncles>
        <Aunts>
            <Capacity>1</Capacity>
            <XmlRefTests-Person exs:reference="1" />
        </Aunts>
    </XmlRefTests-Person>
</List>

The output I'm after:

<?xml version="1.0" encoding="utf-8"?>
<List>
    <XmlRefTests-Person>
        <Name>Princess Eugenie</Name>
        <Uncles>
            <XmlRefTests-Person id="2">
                <Name>Price Charles</Name>
            </XmlRefTests-Person>
            <XmlRefTests-Person id="3">
                <Name>Price Andrew</Name>
            </XmlRefTests-Person>
            <XmlRefTests-Person id="4">
                <Name>Price Edward</Name>
            </XmlRefTests-Person>
        </Uncles>
        <Aunts>
            <XmlRefTests-Person id="1">
                <Name>Princess Anne</Name>
            </XmlRefTests-Person>
        </Aunts>
    </XmlRefTests-Person>
    <XmlRefTests-Person>
        <Name>Princess Beatrice</Name>
        <Uncles>
            <XmlRefTests-Person ref="2" />
            <XmlRefTests-Person ref="3" />
            <XmlRefTests-Person ref="4" />
        </Uncles>
        <Aunts>
            <XmlRefTests-Person ref="1" />
        </Aunts>
    </XmlRefTests-Person>
</List>

And my test program:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using ExtendedXmlSerializer;
 using ExtendedXmlSerializer.Configuration;
 using ExtendedXmlSerializer.ExtensionModel;
 					
 public class Program
 {
	public static void Main()
	{
		IExtendedXmlSerializer_Serialize_ProducesCustomXml();
	}
	
	public static void IExtendedXmlSerializer_Serialize_ProducesCustomXml()
	{
		//arrange
		string result = null;
		var people = new List<Person> { new Person("Princess Eugenie"), new Person("Princess Beatrice") };
		var aunts = new List<Person> { new Person("Princess Anne") };
		var uncles = new List<Person> { new Person("Price Charles"), new Person("Price Andrew"), new Person("Price Edward") };
		people[0].Aunts = aunts;
		people[0].Uncles = uncles;
		people[1].Aunts = aunts.ToList();
		people[1].Uncles = uncles.ToList();

		IExtendedXmlSerializer serializer = new ConfigurationContainer()
			.EnableReferences()
			.UseOptimizedNamespaces()
			.EnableImplicitTyping(typeof(Person))
			.Create();

		//test
		result = serializer.Serialize(people);

		//assert
		Console.WriteLine(result);
		if (result != @"<?xml version=""1.0"" encoding=""utf-8""?><List><XmlRefTests-Person><Name>Princess Eugenie</Name><Uncles><XmlRefTests-Person id=""2""><Name>Price Charles</Name></XmlRefTests-Person><XmlRefTests-Person id=""3""><Name>Price Andrew</Name></XmlRefTests-Person><XmlRefTests-Person id=""4""><Name>Price Edward</Name></XmlRefTests-Person></Uncles><Aunts><XmlRefTests-Person id=""1""><Name>Princess Anne</Name></XmlRefTests-Person></Aunts></XmlRefTests-Person><XmlRefTests-Person><Name>Princess Beatrice</Name><Uncles><XmlRefTests-Person ref=""2"" /><XmlRefTests-Person ref=""3"" /><XmlRefTests-Person ref=""4"" /></Uncles><Aunts><XmlRefTests-Person ref=""1"" /></Aunts></XmlRefTests-Person></List>")
			throw new Exception("Xml mismatch.");
	}
	
	public class Person
	{
		public Person() { }
		public Person(string name)
		{
			Name = name;
		}
		public string Name { get; set; }
		public List<Person> Uncles { get; set; }
		public List<Person> Aunts { get; set; }
	}
 }

Thanks to anyone who reads this :)

@Mike-E-angelo Mike-E-angelo added the question Further information is requested label Apr 4, 2020
@Mike-E-angelo Mike-E-angelo self-assigned this Apr 4, 2020
@Mike-E-angelo
Copy link
Member

Hi @jamesquox thanks for writing in. You will be able to remove a

To address your questions here:

  1. Unfortunately these are considered critical/essential attributes so they cannot be removed without breaking functionality with expected ExtendedXmlSerializer syntax.
  2. You can get a little more out of removing unwanted namespaces by adding List<Person> to your EnableImplicitTyping call, so: .EnableImplicitTyping(typeof(Person), typeof(List<Person>)).

If you have specialized requirements to remove additional text/characters/symbols for use with another system, I would for sure recommend using XSLT for this as that is exactly how it is intended to be used. :)

Please let me know if you have any further questions and I will do my best to answer here. 👍

@jamesquox
Copy link
Author

Cheers Mike for the confirmation👍

@RiversJohn
Copy link

Years old and already answered, but i still want to return to this due to it being a rather critical and common feature of XML serialization usecases.

The System.Xml library supports overriding and attributing namespaces specifically because many of the use cases require explicitly setting something in a given namespace and lack of support for explicit namespaces makes this unsuitable as is for the purpose.

My usecase here being generation of a model with varying namespaces depending on who's asking, i could either duplicate thousands of lines of code, or control this one feature that is supported by the underlying Xml.

If i can come up with a way to support this without breaking functionality or by adding new functionality for one way transformations cleanly, are still open for PR's and reviewing said work should you agree with a proposal?

@Mike-E-angelo
Copy link
Member

Hi @RiversJohn thank you for your inquiry. I am certainly open to working on a PR with you. Primarily, if you can contain the changes in an extension so that users must call a particular method during the container-creation process (and thereby constrain its unintended effects) then that is ideal. Of course, all existing tests must pass, as well.

I also want to be sure you understand that this repo is for all intents and purposes in a maintenance state. Sadly, (even as cool as ExtendedXmlSerializer is) my recommendation these days is to use JSON if possible as that is far better supported by Microsoft these days, and we never really quite got a community to actively support this repository.

That stated, there is always the possibility to build a community here. :) If someone wants to work on a PR with the above goals I will do my best to assist them to head in this direction. 👍

@RiversJohn
Copy link

Thank you for your speedy reply @Mike-E-angelo
I was out severely sick so i couldn't return the courtesy.

I was aware of the maintenance, hence the question if you'd possibly be up for it since this would obviously be quite outside the scope of just maintenance. My personal time at least for the next few months is quite limited but depending on our needs i might be able to devote work time on this if using EXS is the route we pick.

The consumers of the outputs we're generating don't accept JSON, only CSV / XML and they're huge corps meaning there's little probability of influencing them to accept other formats.

I'll get back to you on this if i can go forward with this and check the proposal idea with you to make sure it's compatible in implementation.

@Mike-E-angelo
Copy link
Member

Glad to hear you are feeling better @RiversJohn. 🙏 And for the rest that sounds like a good plan. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants