2013-06-05 81 views
0

XML值I有一個XML文件作爲下閱讀困難使用的XDocument

<ScriptFileNames> 
    <SqlEye> 
    <ScriptFile Name='_ws_CommandHistory_AllHistory.sql' Type='SP' SqlEyeAnalysisTime='00:00:01.7817594' FxCopAnalysisTime='00:00:00.2253670' FxCopWarningCount='0' SqlEyeWarningCount='2'> 
      <SqlEyeWarnings> 
      <SqlEyeWarning message='SD004: Check for existence object then Drop statement before create statement' /> 
      <SqlEyeWarning message='SP001: Set NoCount statement missing or it should be ON.' /> 
      </SqlEyeWarnings> 
     </ScriptFile> 
    </SqlEye> 
</ScriptFileNames> 

我想輸出是

FileName WarningMessage格式

例如

_ws_CommandHistory_AllHistory.sql SD004: Check for existence object then Drop statement before create statement 
_ws_CommandHistory_AllHistory.sql SP001: Set NoCount statement missing or it should be ON. 

我嘗試

string input = @"<ScriptFileNames> 
    <SqlEye> 
    <ScriptFile Name='_ws_CommandHistory_AllHistory.sql' Type='SP' SqlEyeAnalysisTime='00:00:01.7817594' FxCopAnalysisTime='00:00:00.2253670' FxCopWarningCount='0' SqlEyeWarningCount='2'> 
      <SqlEyeWarnings> 
      <SqlEyeWarning message='SD004: Check for existence object then Drop statement before create statement' /> 
      <SqlEyeWarning message='SP001: Set NoCount statement missing or it should be ON.' /> 
      </SqlEyeWarnings> 
     </ScriptFile> 
    </SqlEye> 
</ScriptFileNames>"; 
XDocument doc = XDocument.Parse(input); 
      XElement scriptFileNames = doc.Element("ScriptFileNames"); 

      var xx = (from x1 in scriptFileNames.Element("SqlEye").Elements("ScriptFile") 
         select new 
          { 
           Name = x1.Attribute("Name").Value        
          }).ToList(); 

我也有我更多的部分

<SqlEyeRemarks> 
     <SqlEyeRemark message='SD001: Set QuotedIdentifier ON statement is missing or order mismatch or it should be ON.' /> 
     <SqlEyeRemark message='SD002: Set AnsiiNullsOn ON statement is missing or order mismatch or it should be ON.' /> 
     <SqlEyeRemark message='SD009: Missing or order mismatch of Grant statement.' /> 
     </SqlEyeRemarks> 

我怎樣才能讓他們相處?

+0

什麼是輸出?請注意,您當前的代碼不會編譯(您正在嘗試解析'x'而不是'input'),爲了便於閱讀,您應該更合適地縮進它。 –

+0

所需的輸出:FileName WarningMessage ..它將在一個集合中,因爲我正在嘗試 –

+0

而當前輸出? (我注意到你已經修改了變量名,但是代碼仍然是可縮進的。)作爲提示:你目前忽略了你有多個'SqlEyeWarning'元素的事實。你只需要通過'ScriptFile'創建一個條目。 –

回答

1

您目前的代碼只是迭代到ScriptFile的級別。我懷疑最簡單的方法是:

var warnings = doc.Descendants("SqlEyeWarning") 
        .Select(x => new { 
         FileName = (string) x.Parent.Parent.Attribute("Name"), 
         Message = (string) x.Attribute("message") 
        }) 
        .ToList(); 

這使用x.Parent.ParentSqlEyeWarning元素上去過去SqlEyeWarningsScriptFile

我假設全部SqlEyeWarning這裏的元素是在同一種結構內。如果是這樣,以上是最簡單的。否則,您可以使用:

var warnings = doc.Root 
        .Element("SqlEye") 
        .Elements("ScriptFile") 
        .Elements("SqlEyeWarnings") 
        .Elements("SqlEyeWarning") 
        .Select(x => new { 
         FileName = (string) x.Parent.Parent.Attribute("Name"), 
         Message = (string) x.Attribute("message") 
        }) 
        .ToList(); 
0

請參閱下面的代碼,它將向控制檯寫入文件名和相關警告消息。

這種方法會將您的XML反序列化爲可以使用的.NET對象。

一個小提示 - 儘量避免在XML中使用太多的屬性。考慮將ScriptFile屬性轉換爲元素以提高可讀性=](如果您選擇將XmlAttribute屬性更改爲XmlElement,則需要修改代碼以反映更改。

祝你好運!

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Xml.Linq; 
using System.Xml.Serialization; 

namespace ConsoleApplication1 
{ 
    public class Program 
    { 
     static void Main(string[] args) 
     { 
      string input = @"<ScriptFileNames> 
           <SqlEye> 
           <ScriptFile Name='_ws_CommandHistory_AllHistory.sql' Type='SP' SqlEyeAnalysisTime='00:00:01.7817594' FxCopAnalysisTime='00:00:00.2253670' FxCopWarningCount='0' SqlEyeWarningCount='2'> 
             <SqlEyeWarnings> 
             <SqlEyeWarning message='SD004: Check for existence object then Drop statement before create statement' /> 
             <SqlEyeWarning message='SP001: Set NoCount statement missing or it should be ON.' /> 
             </SqlEyeWarnings> 
            </ScriptFile> 
           </SqlEye> 
          </ScriptFileNames>"; 

      XDocument doc = XDocument.Parse(input); 
      XmlSerializer serialiser = new XmlSerializer(typeof(ScriptFileNames)); 
      ScriptFileNames scriptNames = (ScriptFileNames)serialiser.Deserialize(doc.CreateReader()); 

      foreach (SqlEyeWarning warning in scriptNames.SqlEye.ScriptFile.SqlEyeWarnings) 
      { 
       Console.WriteLine(scriptNames.SqlEye.ScriptFile.Name + "\t" + warning.Message); 
      } 

      Console.ReadLine(); 
     } 

     [XmlRoot] 
     public class ScriptFileNames 
     { 
      [XmlElement("SqlEye")] 
      public SqlEye SqlEye { get; set; } 
     } 

     public class SqlEye 
     { 
      [XmlElement("ScriptFile")] 
      public ScriptFile ScriptFile { get; set; } 
     } 

     public class ScriptFile 
     { 
      [XmlArray("SqlEyeWarnings")] 
      [XmlArrayItem("SqlEyeWarning", typeof(SqlEyeWarning))] 
      public SqlEyeWarning[] SqlEyeWarnings { get; set; } 

      [XmlAttribute("Name")] 
      public string Name { get; set; } 

      [XmlAttribute("Type")] 
      public string Type { get; set; } 

      [XmlAttribute("SqlEyeAnalysisTime")] 
      public string SqlEyeAnalysisTime { get; set; } 

      [XmlAttribute("FxCopAnalysisTime")] 
      public string FxCopAnalysisTime { get; set; } 

      [XmlAttribute("FxCopWarningCount")] 
      public string FxCopWarningCount { get; set; } 

      [XmlAttribute("SqlEyeWarningCount")] 
      public string SqlEyeWarningCount { get; set; } 
     } 

     public class SqlEyeWarning 
     { 
      [XmlAttribute("message")] 
      public string Message { get; set; } 
     } 
    } 
}