Сериализовать объект в xml, включая "xsi: schemalocation" и порядок атрибутов

У меня есть этот класс

public class EnvioDTE
{
    [XmlAttribute]
    public string version { get; set; }

    public EnvioDTE()
    {
        this.version = "1.0";
    }
}

Я сериализую его в XML с помощью следующего кода:

EnvioDTE envioDTE = new EnvioDTE();

string xml = "";

var serializer = new XmlSerializer(typeof(EnvioDTE));
var settings = new XmlWriterSettings
{
    Indent = true,
    NewLineChars = "\n",
    OmitXmlDeclaration = false,
    Encoding = Encoding.GetEncoding("ISO-8859-1")
};

using (var stream = new MemoryStream())
{
    using (var xmlWriter = XmlWriter.Create(stream, settings))
    {
        serializer.Serialize(xmlWriter, this);
        xml = Encoding.GetEncoding("ISO-8859-1").GetString(stream.ToArray());
    }
}

Console.WriteLine(xml);

Это дает мне следующий XML:

<?xml version="1.0" encoding="iso-8859-1"?>
<EnvioDTE version="1.0">
</EnvioDTE>

Что мне нужно добавить в свой код, чтобы получить следующие атрибуты?

<?xml version="1.0" encoding="iso-8859-1"?>
<EnvioDTE xmlns="http://www.sii.cl/SiiDte" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sii.cl/SiiDte EnvioDTE_v10.xsd" version="1.0">
</EnvioDTE>

Для меня важен порядок атрибутов.



Я попробовал внести два изменения:

Изменение # 1

[XmlRoot(Namespace = "http://www.sii.cl/SiiDte")] // *** NEW
public class EnvioDTE
{
    [XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")] // *** NEW
    public string schemaLocation { get; set; } // *** NEW
    [XmlAttribute]
    public string version { get; set; }

    public EnvioDTE()
    {
        this.version = "1.0";
    }
}

Изменение # 2

EnvioDTE envioDTE = new EnvioDTE();

string xml = "";

var namespaces = new XmlSerializerNamespaces(); // *** NEW
namespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance"); // *** NEW

var serializer = new XmlSerializer(typeof(EnvioDTE));
var settings = new XmlWriterSettings
{
    Indent = true,
    NewLineChars = "\n",
    OmitXmlDeclaration = false,
    Encoding = Encoding.GetEncoding("ISO-8859-1")
};

using (var stream = new MemoryStream())
{
    using (var xmlWriter = XmlWriter.Create(stream, settings))
    {
        serializer.Serialize(xmlWriter, this, namespaces); // *** NEW
        xml = Encoding.GetEncoding("ISO-8859-1").GetString(stream.ToArray());
    }
}

Console.WriteLine(xml);

С этими изменениями я получаю следующее:

<?xml version="1.0" encoding="iso-8859-1"?>
<EnvioDTE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sii.cl/SiiDte EnvioDTE_v10.xsd" version="1.0" xmlns="http://www.sii.cl/SiiDte">
</EnvioDTE>

И это не тот порядок атрибутов, который мне нужен ...

Согласно xml-спецификация: Обратите внимание, что порядок спецификаций атрибутов в начальном теге или теге пустого элемента не имеет значения.

Alexander Petrov 13.09.2018 21:42

хм хорошо ... но я подпишу этот документ. Это может быть актуально в этом сценарии (не уверен, потому что подписываемая часть - это узел в xml)

sports 13.09.2018 21:47

Порядок элементов в XML имеет значение. Нет упорядочивания атрибутов. Теперь существует ненормативная каноническая форма, в которой говорится, что атрибуты упорядочены по имени, и я ожидаю, что сериализатор следует этому порядку (en.wikipedia.org/wiki/Canonical_XML). В твоем случае?

Flydog57 13.09.2018 22:21
0
3
106
1

Ответы 1

Так вы просто пытаетесь прочитать XML? Я бы сделал это:

XmlReader reader = XmlReader.Create(path, settings);
StringBuilder sb = new StringBuilder();
if (reader != null)
{                           
    while (reader.Read())
    {
        sb.AppendLine(reader.ReadOuterXml());
    }
    doc = new XmlDocument();
    doc.LoadXml(Convert.ToString(sb));

    XmlNodeList xmlNodeList;

    xmlNodeList = doc.GetElementsByTagName("Whatever your tag name");

    for (i = 0; i < xmlNodeList.Count; i++)
    {
        if (xmlNodeList[i].InnerXml.Length > 0)
        {
            foo = xmlNodeList[i].InnerXml;
        }
    }
}

Ладно, вы просто пытаетесь вывести? Тогда сделай это. Я знаю, что это что-то вроде взлома, и, вероятно, есть миллион способов сделать это:

string myXMLstring = "<?xml version=\"1.0\" encoding="iso-8859-1\"?>" +
<EnvioDTE xmlns=\"http://www.sii.cl/SiiDte\"" + 
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
"xsi:schemaLocation=\"http://www.sii.cl/SiiDte EnvioDTE_v10.xsd\"" + 
"version=\"1.0\">" +
"</EnvioDTE>";

Я избежал кавычек и построил это как строку. Вы даже можете добавить \ r \ n в любое время, когда знаете, что вам нужна новая строка. Надеюсь, это поможет. Удачного кодирования!

Я не пытаюсь читать xml, откуда в моем вопросе вы пришли к такому выводу?

sports 14.09.2018 04:31

Другие вопросы по теме