2015-07-10 2 views
0

Я изо всех сил немного, пытаясь найти подходящий способ написания именно этот XML с XmlWriter и подстилающей строки строитель:Пользовательские отступы по умолчанию Xmlns атрибут Wile запись через XmlWriter

<x:node xmlns="uri:default" 
     xmlns:x="uri:special-x" 
     xmlns:y="uri:special-y" 
     y:name="MyNode" 
     SomeOtherAttr="ok"> 
</x:node> 

лучшее, что я до сих пор :

static string GetXml() 
{ 
    var r = new StringBuilder(); 
    var w = XmlWriter.Create(r, new XmlWriterSettings { OmitXmlDeclaration = true }); 
    w.WriteStartElement("x", "node", "uri:special-x"); 
    w.Flush(); 
    r.Append("\n" + new string(' ', 7)); 
    w.WriteAttributeString("xmlns", "x", null, "uri:special-x"); 
    w.Flush(); 
    r.Append("\n" + new string(' ', 7)); 
    w.WriteAttributeString("xmlns", "y", null, "uri:special-y"); 
    w.Flush(); 
    r.Append("\n" + new string(' ', 7)); 
    w.WriteAttributeString("name", "uri:special-y", "vd"); 
    w.Flush(); 
    r.Append("\n" + new string(' ', 7)); 
    w.WriteAttributeString("SomeOtherAttr", "ok"); 
    w.Flush(); 
    w.WriteEndElement(); 
    w.Flush(); 
    return r.ToString(); 
} 

, который создает

<x:node 
     xmlns:x="uri:special-x" 
     xmlns:y="uri:special-y" 
     y:name="vd" 
     SomeOtherAttr="ok" /> 

, но я не могу найти AW ay написать xmlns по умолчанию сразу после узла. Любая попытка приводит к ошибке или другому форматированию.

Любые идеи? Благодаря!

Обновление: возможно, я могу написать его непосредственно в StringBuilder, но я ищу еще ... hm .. правильный подход.

ответ

1

Вы должны были бы на самом деле добавить пространство имен по умолчанию, которые вы в настоящее время не делает:

var sb = new StringBuilder(); 
var writer = XmlWriter.Create(sb, new XmlWriterSettings 
{ 
    OmitXmlDeclaration = true, 
}); 

using (writer) 
{ 
    writer.WriteStartElement("x", "node", "uri:special-x"); 
    writer.WriteAttributeString("xmlns", "uri:default"); 
    writer.Flush(); 
    sb.Append("\n" + new string(' ', 7)); 
    writer.WriteAttributeString("xmlns", "x", null, "uri:special-x"); 
    writer.Flush(); 
    sb.Append("\n" + new string(' ', 7)); 
    writer.WriteAttributeString("xmlns", "y", null, "uri:special-y"); 
    writer.Flush(); 
    sb.Append("\n" + new string(' ', 7)); 
    writer.WriteAttributeString("name", "uri:special-y", "vd"); 
    writer.Flush(); 
    sb.Append("\n" + new string(' ', 7)); 
    writer.WriteAttributeString("SomeOtherAttr", "ok");    
    writer.WriteEndElement(); 
} 

Смотрите эту демо: https://dotnetfiddle.net/994YqW

Это, как говорится, почему вы пытаетесь это сделать ? Просто позвольте ему отформатировать его, как ему нравится, он по-прежнему семантически такой же и совершенно правильный.

+0

Мне нужно сравнить много файлов WPF и их конвертировать в «каноническую» форму, чтобы упростить ее и потенциально использовать результат как инструмент автоматического форматирования для файлов проекта. Для этого документы должны быть отформатированы так, как это делает VS/Resharper + некоторые «канонические» правила, такие как упорядоченные атрибуты и т. Д. –

+0

Это имеет смысл. Обычно XML не предназначен для потребления человеком, но XAML - это особый случай! –

1

Почему так сложно? Попробуйте пожалуйста:

var r = new StringBuilder(); 

var settings = new XmlWriterSettings 
{ 
    OmitXmlDeclaration = true, 
    NewLineOnAttributes = true, 
    Indent = true, 
    IndentChars = "\t" 
}; 

using (var w = XmlWriter.Create(r, settings)) 
{ 
    w.WriteStartElement("x", "node", "uri:special-x"); 

    w.WriteAttributeString("xmlns", "x", null, "uri:special-x"); 
    w.WriteAttributeString("xmlns", "y", null, "uri:special-y"); 
    w.WriteAttributeString("name", "uri:special-y", "vd"); 
    w.WriteAttributeString("SomeOtherAttr", "ok"); 

    w.WriteEndElement(); 
} 

Все пространства имен будут находиться на одной линии.

+0

Спасибо, хороший. Есть ли что-то вроде NewLineOnAttributes, но и для пространств имен? –

+0

@AlexAtNet К сожалению, нет. –