代码之家  ›  专栏  ›  技术社区  ›  autonomatt

无法访问DataContractSerializer之后的元素

  •  0
  • autonomatt  · 技术社区  · 16 年前

    我有一个简单的对象,我正试图使用DataContractSerializer进行序列化。

    在我的单元测试中,我试图验证XML是否包含产品/sku节点的正确值。

    我的产品类别:

    [DataContract(Namespace = "http://foo.com/catalogue/")
    partial class Product
    {
       [DataMember(Name = "sku")]
       public virtual string ProductSKU
       {
          get { return _productSKU; }
          set
          {
             OnProductSKUChanging();
            _productSKU = value;
            OnProductSKUChanged();
          }
       }
    }
    

    我测试的方法如下:

    public XDocument GetProductXML(Product product)
        {
            var serializer = new DataContractSerializer(typeof(Product));
            var document = new XDocument();
    
            using (var writer = document.CreateWriter())
            {
                serializer.WriteObject(writer, product);
                writer.Close();
            }
    
            return document;
        } 
    

    这是我的单元测试:

    [Test]
        public void Can_get_product_xml()
        {
            // Arrange
            var product = new Product {Id = 1, Name = "Foo Balls", ProductSKU = "Foo123"};
            var repository = new CatalogueRepository();
            var expectedProductSKU = "Foo123";
    
            // Act
            var xml = repository.GetProductXML(product);
            var actualProductSKU = xml.Element("product").Element("sku").Value;
    
            // Assert
            Assert.AreEqual(expectedProductSKU, actualProductSKU);
        }
    

    问题是,当我尝试访问XML元素时,我会得到一个空引用,即使当我设置一个断点时,var xml包含:

    <product xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://foo.com catalogue/">
      <sku>Foo123</sku> 
    </product>
    

    你知道为什么这样不行吗?在将序列化流添加到XDocument之前,是否需要分析它?

    1 回复  |  直到 16 年前
        1
  •  1
  •   marc_s MisterSmith    16 年前

    我认为问题在于您的XML文档有一个XML名称空间 xmlns="http://foo.com catalogue/" 但是当您选择使用linq-to-xml时,您永远不会以任何方式、形状或形式使用该名称空间。

    此外, <product> 标记是XML根标记-不能将其作为元素引用。

    尝试如下操作:

    XNamespace ns = "http://foo.com/catalogue/";
    
    var root = xml.Root;
    var sku = root.Element(xns + "sku").Value;
    

    如果你想确定,先分配 .Element() 到变量并检查 != null

    var sku = root.Element(xns + "sku");
    if(sku != null)
    {
       var skuValue = first.Value;
    }
    

    希望能有所帮助!