2016-11-11 28 views
1

我想从我的Xml文件中读取文本节点的列表。当我尝试读取列出的文本元素中的一个的子节点时,即使XDocument节点看起来被填满,我也会得到NullReference异常。 NullReference异常在行foreach (XElement textElement in textElements)上抛出,这意味着列表textElements的Count> 1,因此它不应该为空。这就像调试器愿意去的那样。Linq XML NullReference异常阅读元素列表

我是否以错误的方式阅读了Xml,或者我不允许/不应该按照我现在的方式构建XElement列表?

这是我的XML文件

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE Book SYSTEM "Book.dtd"[]> 
<album version="0.2" settingsVersion="1"> 
    <size /> 
    <cover /> 
    <inner> 
    <page> 
     <pagenumber>1</pagenumber> 
     <image>1.jpg</image> 
     <text> 
     <value>Test </value> 
     <font>arial</font> 
     <size>18pt</size> 
     <style>normal</style> 
     <weight>normal</weight> 
     <color>#77DD44</color> 
     <rotation>0</rotation> 
     <alignment>start</alignment> 
     <position> 
      <x>50</x> 
      <y>50</y> 
     </position> 
     </text> 
     <text> 
      <value>Test 2 </value> 
      <font>arial</font> 
      <size>18pt</size> 
      <style>normal</style> 
      <weight>normal</weight> 
      <color>#77DD44</color> 
      <rotation>0</rotation> 
      <alignment>start</alignment> 
      <position> 
      <x>50</x> 
      <y>50</y> 
      </position> 
     </text> 
    </page> 
    </inner> 
</album> 

inner可以容纳多个page元素和page可以容纳多个text元素。

我用下面的方法读取了Xml。

List<XElement> pageElements = doc.Root.Element("inner").Elements("page").ToList(); 
foreach (XElement pageElement in pageElements) 
{ 
    string pageNumberString = pageElement.Element("pagenumber").Value; 
    int pageNumberValue = Convert.ToInt32(pageNumberString); 
    string fileNameValue = pageElement.Element("image").Value; 
    // Verify if the currently looped page is the same as the one selected by the user. 
    if (pageNumberValue == pageNumber) 
    { 
     // Get all text nodes from the found page. 
     List<XElement> textElements = pageElement.Elements("text").ToList(); 
     // If no text nodes found return the page with an empty TextInfo array. 
     if (textElements.Count == 0) 
     { 
      PageInfo pageInfoNoText = new PageInfo { PageNumber = pageNumberValue, FileName = fileNameValue, Text = new TextInfo[0] }; 
      Logger.log("PageInfo found for collection {0}. Info {1}", collectionId, pageInfoNoText); 
      return pageInfoNoText; 
     } 
     // If text nodes are found build a list of TextInfo objects and build a new PageInfo object. 
     else 
     { 
      // All text elements in the XML under the found page. 
      List<TextInfo> textInfoList = new List<TextInfo>(); 
      TextInfo[] textArray = new TextInfo[0]; 

      #region Load all required text data from the XML file and build the textList. 
      foreach (XElement textElement in textElements) 
      { 
       string textValue = textElement.Element("value").Value; 

       string fontValue = textElement.Element("font").Value; 

       string fontSizeValue = textElement.Element("size").Value; 

       string styleValue = textElement.Element("style").Value; 

       string weightValue = textElement.Element("weight").Value; 

       string colorValue = textElement.Element("color").Value; 

       string rotationString = textElement.Element("rotation").Value; 
       int rotationValue = Convert.ToInt32(rotationString); 

       string alignmentValue = textElement.Element("alignment").Value; 

       string positionXString = textElement.Element("x").Value; 
       int positionXValue = Convert.ToInt32(positionXString); 

       string positionYString = textElement.Element("y").Value; 
       int positionYValue = Convert.ToInt32(positionYString); 

       // Build Info objects. 
       PositionInfo tempPositionInfo = new PositionInfo 
       { 
        X = positionXValue, 
        Y = positionYValue 
       }; 

       TextInfo tempTextInfo = new TextInfo 
       { 
        Value = textValue, 
        Font = fontValue, 
        Size = fontSizeValue, 
        Style = styleValue, 
        Weight = weightValue, 
        Color = colorValue, 
        Rotation = rotationValue, 
        Alignment = alignmentValue, 
        Position = tempPositionInfo 
       }; 

       textInfoList.Add(tempTextInfo); 

      } 
      textArray = textInfoList.ToArray(); 
      #endregion 

      PageInfo pageInfo = new PageInfo 
      { 
       PageNumber = pageNumberValue, 
       FileName = fileNameValue, 
       Text = textArray 
      }; 
      Logger.log("PageInfo found for collection {0}. Info: {1}", collectionId, pageInfo); 
      return pageInfo; 

     } 
    } 
} 

任何帮助/见解是赞赏!

回答

1

你的代码是好的,但有当你x和y的值,你需要得到position元素的x和y值,如下

string positionXString = (string)textElement.Element("position").Element("x").Value; 
int positionXValue = Convert.ToInt32(positionXString); 
string positionYString = (string)textElement.Element("position").Element("y").Value; 
int positionYValue = Convert.ToInt32(positionYString); 
+0

刚刚发现,以及。键入这个主题有助于让我的脑袋出现代码并重置。感谢您的快速评论! –

1

文本元素不包含名为x的元素,因而试图访问一个NullReferenceException X结果的价值:

string positionXString = textElement.Element("x").Value; 
// textElement.Element("x") is null, "x" is in textElement.Element("position") 
int positionXValue = Convert.ToInt32(positionXString); 

你可以使用后代(后代(“X”)更好FirstOrDefault ()?. Value)而不是Element,但总体而言,您可能想要完全重构它。

+0

是的,我只是发现它藏汉一个错误。键入这个主题有助于让我的脑袋出现代码并重置。感谢您的快速评论! –