如何从xml中搜索反序列化的类以获取特定值,并将节点放入其中

时间:2015-02-13 16:10:14

标签: c# .net xml class serialization

我有一个xml文档,它是从类生成然后序列化的。后来,我对数据进行了反序列化,并使用了相同的类结构。我目前有一个充满对象的变量。我现在需要的是能够搜索每个对象的特定值,如果该值存在,则将新数据作为子项追加。我在.NET中使用了Reflection和GetValue属性,但却变得相当困惑。下面是一些示例代码。

谢谢。

public class Root
{
    [XmlElement("Product")]
    public List<Product> Product { get; set; }

    [XmlElement("Modification")]
    public List<Modification> Modification { get; set; }
}

public class Product
{
    public string ProductID { get; set; }
    public string ProductName { get; set; }
    public List<ColorVariants> ColorVariants { get; set;}
    public List<FeatureAddOns> FeatureAddOns { get; set; }
}

DataTable DTFeatureAddOn = new DataTable();
DTFeatureAddOn.Columns.Add("ProductID", typeof(String));
DTFeatureAddOn.Columns.Add("ProductName", typeof(String));

DataRow drDTFeatureAddOn = DTFeatureAddOn.NewRow();
drDTFeatureAddOn["ProductID"] = "ProductID";
drDTFeatureAddOn["ProductName"] = "ProductName";

DTFeatureAddOn.Rows.Add(drDTFeatureAddOn);

catalogFeed = DeserializeCatalogFeed();

if (DTFeatureAddOn.Rows.Count > 0)
{
    foreach (DataRow row in DTFeatureAddOn.Rows)
{
//a. For each unique ProductID, first check to make sure the does not exist – if NOT then create
    List<int> ProductIDList = new List<int>();
    PropertyInformation pinfo = typeof(Root).GetProperty("ProductID");
    //foreach (catalogFeed.Product
    //b. For each PlacementCode, create a structure FeatureAddOn below that ProductID.  This may results into a list of FeatureAddons for a given ProductID
    }


SerializeToXML(catalogFeed, DeltaCatalogFeedUpload.FileName);
}

    public static void SerializeToXML(Root rootNode, string FileName)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Root));
        TextWriter tw = new StreamWriter(FileName);
        serializer.Serialize(tw, rootNode);
        tw.Close();
    }

    public static Root DeserializeFromXML()
    {
        XmlSerializer deserializer = new XmlSerializer(typeof(Root));
        TextReader textReader = new StreamReader(DeltaCatalogFeedUpload.FileName);
        Root nodes;
        nodes = (Root)deserializer.Deserialize(textReader);
        textReader.Close();

        return nodes;
    }

    public static Root DeserializeCatalogFeed()
    {
        Root root = new Root();
        try
        {

            FileInfo fInfo = new FileInfo(DeltaCatalogFeedUpload.FileName);
            if (fInfo.Exists)
            {

                root = DeserializeFromXML();

            }
            else
            {
                root.Product = new List<Product>();
                root.Modification = new List<Modification>();
                root.PlacementCodeList = new List<PlacementCodeList>();
                root.AssociatedSKU = new List<AssociatedSKU>();
                root.FontStyle = new List<FontStyle>();
                root.FontSize = new List<FontSize>();
                root.FontType = new List<FontType>();
                root.Alignment = new List<Alignment>();
                root.ThreadColor = new List<ThreadColor>();                    
                root.Category = new List<Category>();
                root.ProductLine = new List<ProductLine>();
                root.ProductStock = new List<ProductStock>();
                root.ProductFiber = new List<ProductFiber>();                    
                root.ProductFabric = new List<ProductFabric>();
                root.Season = new List<Season>();
            }
        }
        catch (Exception e)
        {
            // do something with the error but always return a price list
            root.Product = new List<Product>();
            root.Modification = new List<Modification>();
            root.PlacementCodeList = new List<PlacementCodeList>();
            root.AssociatedSKU = new List<AssociatedSKU>();
            root.FontStyle = new List<FontStyle>();
            root.FontSize = new List<FontSize>();
            root.FontType = new List<FontType>();
            root.Alignment = new List<Alignment>();
            root.ThreadColor = new List<ThreadColor>();
            root.Category = new List<Category>();
            root.ProductLine = new List<ProductLine>();
            root.ProductStock = new List<ProductStock>();
            root.ProductFiber = new List<ProductFiber>();
            root.ProductFabric = new List<ProductFabric>();
            root.Season = new List<Season>();
        }
        return root;
    }

1 个答案:

答案 0 :(得分:0)

听起来你正在寻找LINQ to Objects

catalogFeed.ProductProduct个对象(List<Product>)的列表。就个人而言,我会将该属性命名为Products,但这只是为了便于阅读。

假设您的代码中Product类具有名为ProductID的属性,并且您希望匹配该属性。

我会创建一个以Product为对象的ProductID对象字典。通过ToDictionary LINQ方法执行此操作:

var productLookup = catalogFeed.Product.ToDictionary(p => p.ProductID);

然后在循环数据表中,您可以在字典中找到匹配的产品。

foreach (DataRow row in DTFeatureAddOn.Rows)
{
    var productId = row["ProductID"];
    if (productLookup.ContainsKey(productId))
    {
        var matchingProduct = productLookup[productId];
        // get whatever you need out of the matching product.
    }
}

您可以使用LINQ查询在循环的每次迭代中找到匹配的产品,但使用ToDictionary方法意味着列表的扫描只发生一次。它本质上是创建一个内存索引,因此您可以快速找到您要查找的对象,而无需每次都扫描整个列表,但如果您确实想要这样做,请ProductID用{var matchingProduct = catalogFeed.Product.FirstOrDefault(p => p.ProductID = desiredProductID); 查找单个匹配的产品{3}}看起来像这样:

matchingProduct

如果没有匹配,则null将是{{1}}。