C# 如何将子元素移动到父元素的属性(XML)
我目前有一个相当大的C# 如何将子元素移动到父元素的属性(XML),c#,xml,xml-serialization,C#,Xml,Xml Serialization,我目前有一个相当大的XML文件(大约800MB)。我已经尝试了一些尝试(是一个处理压缩的尝试)在它当前的状态下使用它;然而,它们并不是很成功,因为它们需要相当长的时间 XML文件结构类似于以下内容(生成日期早于我): 据我所知,我只需将xmldattribute标记添加到文件中,它将使用该标记作为属性编写文件的所有未来版本;然而,有人告诉我,为了将数据从旧的方式转换为新的方式,我可能需要某种我不确定的“活页夹” 这里的任何建议都会很有帮助 注意:我知道也可以采取以下措施来减少文件大小(减少28%
XML
文件(大约800MB
)。我已经尝试了一些尝试(是一个处理压缩的尝试)在它当前的状态下使用它;然而,它们并不是很成功,因为它们需要相当长的时间
XML
文件结构类似于以下内容(生成日期早于我):
据我所知,我只需将xmldattribute
标记添加到文件中,它将使用该标记作为属性编写文件的所有未来版本;然而,有人告诉我,为了将数据从旧的方式转换为新的方式,我可能需要某种我不确定的“活页夹”
这里的任何建议都会很有帮助
注意:我知道也可以采取以下措施来减少文件大小(减少28%):
更新:我目前正试图简单地在属性上使用xmldattribute
标记,但遇到了一个错误(我预料到),其中反序列化时反射失败:
反映类型DemoClass
时出错
更新2:现在从新的角度工作;我决定复制所有需要的类,用xmldattribute
标记更新它们;然后用旧类加载旧文件,用新类编写新文件。如果这能奏效,那将是一个很好的解决办法。然而,我相信有一种方法可以做到这一点,而不需要这种变通方法
更新3:更新2(上面)中的方法没有按我预期的方式工作,结果遇到了问题。由于这种方法也涉及大量内容,我最终编写了一种自定义转换方法,使用原始序列化加载XML
,然后使用System.XML.Linq
命名空间中的XDocument
,手动创建了一个新的XML
文档。这最终是一项耗时的任务,但从长远来看,总体变化较小。它以预期的方式序列化文件(当然这里和那里会有一些调整)。下一步是更新旧的序列化,因为旧文件已经转换。在这一过程中,我已经完成了大约80%的过程,仍然在这里和那里遇到了一些颠簸:
不能为基元类型指定XmlAttribute的类型
尝试反序列化
枚举
值时会发生这种情况。序列化程序似乎认为它是一个字符串
值
static void Main()
{
var element=XElement.Load(@“C:\Users\user\Downloads\CollectionOfObjects.xml”);
元素属性(元素);
保存(@“C:\Users\user\Downloads\CollectionOfObjects copy.xml”);
}
静态void元素属性(XElement元素)
{
foreach(element.Elements().ToList()中的变量el)
{
如果(!el.HasAttributes&&!el.HasElements)
{
var属性=新的XAttribute(el.Name,el.Value);
元素。添加(属性);
el.移除();
}
其他的
元素属性(el);
}
}
今天早些时候我回答了类似的问题。看看我的回答,看看你是否可以使用代码。我会修改,如果你有必要,但需要更多的细节。请参阅:@jdweng我曾考虑过使用XSLT
,对于这个更改来说,它太复杂了一点。这是一个一次性的改变,永远不会被重复使用。我建议使用XmlReader和XMLLINQ,我知道这是可行的。
<Name>Something</Name>
<Description>Some description.</Description>
<CollectionOfObjects>
<Object>
<Name>Name Of Object</Name>
<Description>Description of object.</Description>
<AltName>Alternate name</AltName>
<ContainerName>Container</ContainerName>
<Required>true</Required>
<Length>1</Length>
<Info>
<Name>Name</Name>
<File>Filename</File>
<Size>20</Size>
<SizeUnit>MB</SizeUnit>
</Info>
</Object>
</CollectionOfObjects>
<CollectionOfObjects Name="Something" Description="Some description.">
<Object Name="Name Of Object" AltName="Alternate name" Container="Container" Required="true" Length="1" Description="Description of object.">
<Info Name="Name" File="Filename" Size="20" SizeUnit="MB" />
</Object>
</CollectionOfObjects>
internal class DemoClass {
[CategoryAttribute("Properties"), DescriptionAttribute("The name of this object.")]
public string Name { get; set; }
}
internal bool Serialize(DemoClass demo, FileStream fs) {
XmlSerializer serializer = new XmlSerializer(typeof(DemoClass));
XmlWriterSettings settings = null;
XmlWriter writer = null;
bool result = true;
try {
settings = new XmlWriterSettings() {
Indent = true,
IndentChars = ("\t"),
Encoding = Encoding.UTF8,
NewLineOnAttributes = false,
NewLineChars = Environment.NewLine,
NewLineHandling = NewLineHandling.Replace
};
writer = XmlWriter.Create(fs, settings);
serializer.Serialize(writer, demo);
} catch { result = false; } finally { writer.Close(); }
return result;
}
Indent = false,
Encoding = Encoding.UTF8,
NewLineOnAttributes = false,