Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将子元素移动到父元素的属性(XML)_C#_Xml_Xml Serialization - Fatal编程技术网

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,