c# - 使用命名空间处理 C# XML 反序列化

标签 c# xml serialization namespaces

我一直在努力反序列化以下 XML 文档:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:settings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main" mc:Ignorable="w14 w15">
    <w:zoom w:percent="100"></w:zoom>
    <w:proofState w:spelling="clean" w:grammar="clean"></w:proofState>
    <w:defaultTabStop w:val="720"></w:defaultTabStop>
    <w:characterSpacingControl w:val="doNotCompress"></w:characterSpacingControl>
    <w:compat>
        <w:compatSetting w:name="compatibilityMode" w:uri="http://schemas.microsoft.com/office/word" w:val="15"></w:compatSetting>
        <w:compatSetting w:name="overrideTableStyleFontSizeAndJustification" w:uri="http://schemas.microsoft.com/office/word" w:val="1"></w:compatSetting>
        <w:compatSetting w:name="enableOpenTypeFeatures" w:uri="http://schemas.microsoft.com/office/word" w:val="1"></w:compatSetting>
        <w:compatSetting w:name="doNotFlipMirrorIndents" w:uri="http://schemas.microsoft.com/office/word" w:val="1"></w:compatSetting>
        <w:compatSetting w:name="differentiateMultirowTableHeaders" w:uri="http://schemas.microsoft.com/office/word" w:val="1"></w:compatSetting>
    </w:compat>
    <w:rsids>
        <w:rsidRoot w:val="00B31FC7"></w:rsidRoot>
        <w:rsid w:val="00251096"></w:rsid>
        <w:rsid w:val="00481AA7"></w:rsid>
        <w:rsid w:val="005C6856"></w:rsid>
        <w:rsid w:val="00661DE2"></w:rsid>
        <w:rsid w:val="00984D97"></w:rsid>
        <w:rsid w:val="00A06ADC"></w:rsid>
        <w:rsid w:val="00B31FC7"></w:rsid>
    </w:rsids>
    <m:mathPr>
        <m:mathFont m:val="Cambria Math"></m:mathFont>
        <m:brkBin m:val="before"></m:brkBin>
        <m:brkBinSub m:val="--"></m:brkBinSub>
        <m:smallFrac m:val="0"></m:smallFrac>
        <m:dispDef></m:dispDef>
        <m:lMargin m:val="0"></m:lMargin>
        <m:rMargin m:val="0"></m:rMargin>
        <m:defJc m:val="centerGroup"></m:defJc>
        <m:wrapIndent m:val="1440"></m:wrapIndent>
        <m:intLim m:val="subSup"></m:intLim>
        <m:naryLim m:val="undOvr"></m:naryLim>
    </m:mathPr>
    <w:themeFontLang w:val="en-US"></w:themeFontLang>
    <w:clrSchemeMapping w:bg1="light1" w:t1="dark1" w:bg2="light2" w:t2="dark2" w:accent1="accent1" w:accent2="accent2" w:accent3="accent3" w:accent4="accent4" w:accent5="accent5" w:accent6="accent6" w:hyperlink="hyperlink" w:followedHyperlink="followedHyperlink"></w:clrSchemeMapping>
    <w:shapeDefaults>
        <o:shapedefaults v:ext="edit" spidmax="1026"></o:shapedefaults>
        <o:shapelayout v:ext="edit">
            <o:idmap v:ext="edit" data="1"></o:idmap>
        </o:shapelayout>
    </w:shapeDefaults>
    <w:decimalSymbol w:val="."></w:decimalSymbol>
    <w:listSeparator w:val=","></w:listSeparator>
    <w15:chartTrackingRefBased></w15:chartTrackingRefBased>
    <w15:docId w15:val="{23720E07-DD19-46BC-8098-ED32713AB32B}"></w15:docId>
</w:settings>

我只对 rsids 元素中包含的内容感兴趣。所以我想我可以创建看起来像这样的类:
 [XmlRoot(ElementName ="settings", Namespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main")]
    public class rsids
    {
        [XmlElement(ElementName ="rsids",Namespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main")]
        public List<rsid> Rsids { get; set; }
    }

    public class rsid
    {
        [XmlAttribute(Namespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main")]
        public static string val { get; set; }
    }

我正在尝试像这样反序列化:
XDocument xdoc = XDocument.Load(file);
        using (TextReader reader = new StringReader(xdoc.ToString()))
        {
            try
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(rsids));
                StreamReader sr = new StreamReader(file);
                rsids SettingsXml = (rsids)xmlSerializer.Deserialize(sr);

                foreach (var rsid in SettingsXml.Rsids)
                {
                    Console.WriteLine(rsid.val.Count());
                }

                Console.ReadLine();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.ReadLine();
            }
        }

但是,我收到以下错误:“值不能为空”。这是我第一次尝试使用命名空间反序列化 XML 文档。我浏览了社区,发现了很多有类似问题的人的文章,但是,在尝试了其中一些解决方案后,我和刚开始时一样困惑,只是在兜圈子。我想明白这一点。一些已发布的解决方案似乎表明我只需要向我的装饰器(命名空间 =“”)添加一个空白的命名空间属性,而其他的则显示被引用的实际命名空间 uri 但仅针对根元素在后续元素\属性中留下空白.我更多的是寻找关于“为什么”\“何时”使用一种方法而不是另一种方法的教育,以及如何在下面给出的 XML 的情况下完成此任务的示例。感谢您提供的任何帮助。

干杯

最佳答案

你离得太远了。

  • 您的 XmlElement属性意味着多个 rsids元素。你要的是单例rsids包含多个 rsid 的元素元素。最简单的方法是使用 XmlArrayXmlArrayItem属性。
  • val属性不应该是 static
  • 由于看起来像 a bug in XmlSerializer ,您需要包含 Form = XmlSchemaForm.Qualified在您的 XmlAttribute属性。

  • 您也可以省略大部分 Namespace属性,因为它们将被继承,以及 ElementName不必明确指定。

    把所有这些放在一起:
    [XmlRoot(Namespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main")]
    public class settings
    {
        [XmlArray("rsids")]
        [XmlArrayItem("rsid")]
        public List<rsid> Rsids { get; set; }
    }
    
    public class rsid
    {
        [XmlAttribute(Form = XmlSchemaForm.Qualified)]
        public string val { get; set; }
    }
    

    当然,如果这就是您想要的,那么简单的 LINQ to XML 查询会容易得多:
    XNamespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
    
    var rsids = doc.Descendants(w + "rsid")
        .Attributes(w + "val")
        .Select(x => x.Value);
    

    this fiddle对于这两种方法的工作演示。

    关于c# - 使用命名空间处理 C# XML 反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42004489/

    相关文章:

    c# - 如何在 MVC 模型中创建独特的字段?

    java - 流损坏异常 : invalid type code: 01 in Client Server connection

    java - Jackson:在将对象序列化为 json 时自定义转义双引号

    c# - 为什么我的 .NET 启动时间随着预生成的序列化程序集而增加?

    c# - ASP.Net core Azure Webjob (SDK 3.0.10) DI 无法解析

    c# - 错误的连接字符串 NHibernate 3.3

    c# - 与 ServiceStack.OrmLite 的左连接返回一个空对象而不是 null

    Java servlet json对象包含XML,编码问题

    javascript - jquery 1.6.1 - 选择 xml

    java - 重新排序 XML 标签