2015-02-12 2 views
0

Учитывая следующий XML:C#: десериализации неизвестных элементов XML в массив или список

<browser> 
    <firefox company="mozilla"></firefox> 
    <chrome company="google"></chrome> 
    <ie company="microsoft"></ie>  
</browser> 

Это мой код для десериализации:

[XmlRoot("browser")] 
public class Browser 
{ 
    //--List or Array 
    List<BrowserType> browserTypes {get; set;} 
} 

public class BrowserType 
{ 
    [XmlAttribute("company")] 
    public string company {get; set;} 
} 

XmlSerializer xmlSerializer = new XmlSerializer(typeof(Browser)); 
StreamReader sr = new StreamReader("browser.xml"); 
Browser browser = (Browser)xmlSerializer.Deserialize(sr); 

foreach(var item in browserTypes) 
{ 
    //--List browser types 
} 

Для решения этой проблемы я не могу сделать следующий код для XmlArrayItem, так как я не знаю имя элемента.

[XmlArray("browser")] 
[XmlArrayItem("firefox")] 
public BrowserType[] BrowserTypes{ get; set; } 

Как десериализовать неизвестные элементы xml в массив или список?

ответ

0

Update

Итак, с помощью XML-сериализации, вы можете указать список BrowserType с, а затем указать XmlElement имя и тип для каждого из производных типов. Пример:

[XmlRoot("browser")] 
public class Browser 
{ 
    private readonly List<BrowserType> _items = new List<BrowserType>(); 
    [XmlElement("firefox", typeof(Firefox))] 
    [XmlElement("chrome", typeof(Chrome))] 
    [XmlElement("ie", typeof(IE))] 
    public List<BrowserType> Items { get { return _items; } } 
} 

public class BrowserType 
{ 
    [XmlAttribute("company")] 
    public string Company { get; set; } 
} 

public class Firefox : BrowserType 
{ 
} 

public class Chrome : BrowserType 
{ 
} 


public class IE : BrowserType 
{ 
} 

Оригинал запись:

Если вы можете переключиться на XDocument вместо этого, то вы могли бы захватить все потомки корневого узла, а затем получить имя каждого потомка. Пример:

static void Main(string[] args) 
    { 
     string xmlString = @"<browser> 
<firefox company=""mozilla""></firefox> 
<chrome company=""google""></chrome> 
<ie company=""microsoft""></ie>  
</browser>"; 

     XDocument xdoc = XDocument.Parse(xmlString); 
     var elementNames = xdoc.Root.Descendants()  // Get the descendants of the root node 
            .Select(element => element.Name.LocalName);  // Project each XElement to its name 
     string[] browserTypes = elementNames.ToArray(); 

     foreach (string browserType in browserTypes) 
     { 
      Console.WriteLine(browserType); 
     } 
    } 

Выход:

firefox 
chrome 
ie 
+0

да я могу получить эти элементы с помощью LINQ к XML. но то, что я пытаюсь сделать здесь, - это построить классы на основе схемы xml. Я ожидаю иметь что-то вроде [XmlArray («браузер»)] [XmlArrayItem («firefox»)] public BrowserType [] BrowserTypes {get; задавать; } – jmc

+0

спасибо за обновленный ответ. я определенно могу это сделать. но только для уточнения, в момент, когда я запускаю десериализацию, программа не знает о элементах. я имею в виду firefox, chrome и т. е. все неизвестные элементы, поэтому я не могу создавать классы для них и определять их в типе XElement(). есть ли способ, которым я могу динамически установить атрибут XElement. хорошо, я смог сделать это с помощью элемента XmlRoot, используя новый XmlRootAttribute («любое имя root u want»), но не уверен, как это сделать для дочерних элементов. – jmc

+0

О, я вижу. Я не знаю, как это сделать. :) В соответствии с этим [принятым ответом] (http://stackoverflow.com/a/23399551/4551527) вы можете использовать XmlDocument или XDocument (например, в моем первоначальном ответе), или он также предложил использовать Json.NET (который, как мне кажется имеет поддержку XML). Удачи! – ama1111

Смежные вопросы