分析 dotnet 中包含两个命名空间的 XML

Parsing XML containing two namespaces in dotnet

提问人:julianuslemurrex 提问时间:9/19/2023 最后编辑:Palle Duejulianuslemurrex 更新时间:9/19/2023 访问量:38

问:

我有一个从 wcf 返回的 xml,我必须将其反序列化为对象。不幸的是,我不能使用 wcf 数据协定,因为我的公司正在停用 WCF,因此此解决方案是临时的。我试图像我的其他反序列化一样使用它,但它不起作用,我认为这是因为 .Result

<ServiceResponse xmlns="http://www.julianuslemurrex.com/MyWcfService/2023/9/19">
    <ServiceResult xmlns:a="http://schemas.datacontract.org/2023/9/MyWcfService.Model.DataTransfer" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:IsEmployee i:nil="true"/>
        <a:IsContractor i:nil="true"/>
        <a:EmployeeReference>EMEM001F1</a:EmployeeReference>
    </ServiceResult>
</ServiceResponse>

我创建了两个类:

[XmlRoot(ElementName="ServiceResponse")]
public class EmployeeDtoRoot
{
    [XmlElement(ElementName="ServiceResult")]
    public EmployeeDto Root { get; set; }
}

[XmlRoot("ServiceResult")]
public class EmployeeDto
{
    [XmlElement("IsEmployee")]
    public bool IsEmployee { get; set; }

    [XmlElement("IsContractor")]
    public bool IsContractor { get; set; }

    [XmlElement("EmployeeReference")]
    public string EmployeeReference { get; set; }
}

反序列化部分代码:

using (XmlTextReader xtr = new XmlTextReader(xmlToDeserialize))
{
    XmlSerializer serializer = new XmlSerializer(typeof(EmployeeDtoRoot));
    
    xtr.Namespaces = false;
    xtr.DtdProcessing = DtdProcessing.Parse;
    var root = (EmployeeDtoRoot)serializer.Deserialize(xtr);
    var r = root;
}

这两个类以正确的关系连接,但 中的值为空。上面的解决方案应该忽略命名空间,但无论如何都不会解析 xml。EmployeeDto

我该如何解析?甚至不应该是必需的,我只需要 xml 中的三个元素:和 .EmployeeDtoRootIsEmployeeIsContractorEmployeereference

C# .NET .net-core xml 解析

评论

0赞 Jocke 9/19/2023
这些类是从 wsdl 生成的吗?在我看来,两个类都装饰为 ,这看起来很奇怪,内容是什么?XmlRootxmlToDeserialize
0赞 julianuslemurrex 9/19/2023
类必须标记为 XmlRoot。如果是跳过,则由于节点而解析 xml 时出错EmployeeDtoRootServiceResponse
1赞 Peter Dongan 9/19/2023
有时,可以通过序列化虚拟对象并将结果与尝试反序列化的结果进行比较来查明反序列化的问题。

答:

0赞 Peter Dongan 9/19/2023 #1

IsEmployee 和 IsContractor 在 XML 中都是 null,但在类定义中它们不能为 null。

    <a:IsEmployee i:nil="true"/>
    <a:IsContractor i:nil="true"/>

因此,EmployeeDto 应如下所示:

[XmlRoot("ServiceResult")]
public class EmployeeDto
{
    [XmlElement("IsEmployee")]
    public bool? IsEmployee { get; set; }

    [XmlElement("IsContractor")]
    public bool? IsContractor { get; set; }

    [XmlElement("EmployeeReference")]
    public string EmployeeReference { get; set; }
}

评论

0赞 julianuslemurrex 9/19/2023
我已将其设置为可为空,但它仍然不起作用。