我正在使用XDocument阅读以下文档:
<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()) {
在foreach中迭代属性,不保留原始XML中属性的原始顺序。也就是说,当我从foreach中再次写出属性时,它们将以与原始XML不同的顺序写出。
示例输出(仅第一个数据节点):
<data id="new_opportunityid" datafieldname="opportunityid" classid="{5546E6CD-394C-4bee-94A8-4425E17EF6C6}"/>
我试图确定是否应用了一些一致性(例如,XElement
解析器是否总是以相反的顺序运行),属性顺序没有可辨别的模式。我还尝试使用XmlReader
而不加载到XDocument
,我尝试从XDocument
而不是MemoryStream
加载XmlReader
。所有方法都会产生相同的结果。
我知道在XML规范中属性顺序并不重要,这对我很重要,因为我在foreach中进行属性值转换,我希望能够将最终文档与原始文档进行区分,而不必考虑到属性的不同排序,但只看到值的变化。它对于源代码控制中的差异大小也很重要。
答案 0 :(得分: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
。嘿presto,属性按照他们进入的顺序出现!!我不知道为什么会这样,但我已经测试了几次并且它是一致的......
答案 1 :(得分:-1)
xe.Attributes
返回C#中属性和集合的集合并不总是保留订单。
参考: Do C# collections always enforce order?
它说Enumerable.Select
保留了订单。你可以亲自尝试一下吗?