Check if an element exists when parsing XML

后端 未结 4 1958
南旧
南旧 2020-12-15 16:17

I\'m parsing XML. I normally parse it the way I show in the code below which is straightforward The problem is that I don\'t own the XML I\'m parsing and I can\'t change it.

相关标签:
4条回答
  • 2020-12-15 16:24

    [Edit]Jon Skeet's answer should be the accepted answer. It is far more readable and easier to apply.[/edit]

    Create an extension method like this :

    public static string TryGetElementValue(this XElement parentEl, string elementName, string defaultValue = null) 
    {
        var foundEl = parentEl.Element(elementName);
    
        if (foundEl != null)
        {
            return foundEl.Value;
        }
    
        return defaultValue;
    }
    

    then, change your code like this :

    select new News()
    {
        id = noticia.TryGetElementValue("IdNoticia"),
        published = noticia.TryGetElementValue("Data"),
        title = noticia.TryGetElementValue("Titol"),
        subtitle = noticia.TryGetElementValue("Subtitol"),
        thumbnail = noticia.TryGetElementValue("Thumbnail", "http://server/images/empty.png")
    };
    

    This approach allows you to keep a clean code with isolating the check of element presence. It also allow you to define a default value, which can be helpful

    0 讨论(0)
  • You could just use the System.Xml.Serialization.XmlSerializer to deserialize it from xml to an object. Then if the element doesn't exist the property of the object will just get it's default value.

    Have a look here: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx or the new path https://docs.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlserializer

    0 讨论(0)
  • 2020-12-15 16:33

    Instead of using the Value property, if you cast to string you'll just get a null reference instead:

    void wc_DownloadStringCompleted(object sender,
                                    DownloadStringCompletedEventArgs e)
    {
        XDocument dataDoc = XDocument.Load(new StringReader(e.Result));
    
        var listitems = from noticia in dataDoc.Descendants("Noticia")
                        select new News()
                        {
                            id = (string) noticia.Element("IdNoticia"),
                            published = (string) noticia.Element("Data"),
                            title = (string) noticia.Element("Titol"),
                            subtitle = (string) noticia.Element("Subtitol"),
                            thumbnail = (string) noticia.Element("Thumbnail")
                        };
    
        itemList.ItemsSource = listitems;
    }
    

    That uses the explicit conversion from XElement to string, which handles a null input by returning a null output. The same is true for all explicit conversions on XAttribute and XElement to nullable types, including nullable value types such as int? - you just need to be careful if you're using nested elements. For example:

    string text = (string) foo.Element("outer").Element("inner");
    

    will give a null reference if inner is missing, but will still throw an exception if outer is missing.

    If you want a "default" value, you can use the null coalescing operator (??):

    string text = (string) foo.Element("Text") ?? "Default value";
    
    0 讨论(0)
  • 2020-12-15 16:50

    You may use the code below:

    string content = item.Element("Content") == null ? "" : item.Element("Content").Value;

    0 讨论(0)
提交回复
热议问题