2016-01-08 2 views
0

Я читаю документ например, следующие с помощью XDocument:XElement сохранить порядок атрибутов

<form> 
    <hiddencontrols> 
     <data classid="{5546E6CD-394C-4bee-94A8-4425E17EF6C6}" datafieldname="opportunityid" id="opportunityid"/> 
     <data classid="{5546E6CD-394C-4bee-94A8-4425E17EF6C6}" datafieldname="producttypecode" id="producttypecode"/> 
    </hiddencontrols> 
</form> 

Примера загрузка:

XmlReader rdr = XmlReader.Create(new System.IO.StringReader(xmlString)); 
XDocument xdoc = XDocument.Load(rdr, LoadOptions.None); 
foreach (XElement xe in xdoc.Root.DescendantsAndSelf()) { 
    if (xe.NodeType == XmlNodeType.Element) { 
     if (xe.HasAttributes) { 
      foreach (XAttribute xa in xe.Attributes()) { 

В рамках Еогеаспа итерировать атрибуты, исходный порядок следования атрибуты в исходном XML НЕ сохраняются. То есть, когда я снова выписываю атрибуты изнутри foreach, они записываются в другом порядке из исходного XML.

Пример вывода (только из первого узла данных):

<data id="new_opportunityid" datafieldname="opportunityid" classid="{5546E6CD-394C-4bee-94A8-4425E17EF6C6}"/> 

Я попытался определить, есть ли некоторая согласованность применяется, существует (например, всегда ли бежит XElement анализатор в обратном порядке, или аналогичный.) не является различимым шаблоном для порядка атрибутов. Я также пытался использовать только XmlReader без загрузки в XDocument, я пробовал загружать XDocument из MemoryStream, а не из XmlReader. Все подходы дают тот же результат.

Я знаю, что в атрибуте атрибута спецификации XML не является существенным, это важно для меня, потому что я делаю преобразование значения атрибута внутри foreach, и я хочу иметь возможность разграничить окончательный документ с оригиналом, не имея для учета различного порядка атрибутов, но просто видя изменения в значениях. Это также имеет значение для размера diff в пределах контроля источника.

+1

Невозможно воспроизвести - см. [Эта скрипка] (https://dotnetfiddle.net/Vc8x3Q), они находятся в порядке документа. Что вы подразумеваете под «выписыванием атрибутов»? –

+1

В стороне, проверка «NodeType» не требуется, 'DescendantsAndSelf' возвращает только элементы. Вы также можете упростить синтаксический анализ, просто используя 'XDocument.Parse (xmlString)'. –

+0

Вы проверили в отладчике, что после того, как читатель/парсер завершится с вашим xml, ваши элементы имеют атрибуты в том порядке, в котором вы хотите? –

ответ

0

Ну, это странно. Я рано утром нашел решение сегодня утром. Это моя текущая последовательность установки для разбора документа:

XDocument xdoc = XDocument.Parse(form.FormXml); 
StringBuilder destXml = new StringBuilder(); 
XmlWriterSettings xrs = new XmlWriterSettings 
{ 
    Indent = false, 
    NewLineChars = String.Empty, 
    WriteEndDocumentOnClose = true 
}; 

XmlWriter xr = XmlWriter.Create(destXml, xrs); 

Изменение я сделал это утро было изменить Indent = false от true и NewLineChars = String.Empty из Environment.NewLine в XmlWriterSettings. Hey presto, атрибуты выходят в том же порядке, в каком они идут! Я понятия не имею, почему это так, но я проверил это несколько раз, и это соответствует ...

-1
xe.Attributes 

возвращает набор атрибутов и коллекций в C# не всегда сохраняет порядок.

Реферировано от: Do C# collections always enforce order?

Это говорит Enumerable.Select сохраняет порядок. Можете ли вы попробовать это для себя и проверить.

Смежные вопросы