2011-04-15 69 views
0

你好,我的代碼如下。我用2個獨立的XML文件來填充組合框(buildermanageremail.xml)並獲得路徑(ANTScripts_Check_In.xml)xml解析需要幫助解決xml文件是否被手動編輯

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.Data; 
using System.Xml.Linq; 

namespace test 
{ 
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public partial class Window1 : Window 
    { 
     DataSet ds = new DataSet(); 
     DataSet ds1 = new DataSet(); 
     public Window1() 
     { 
      InitializeComponent(); 
      PopulateDDL1FromXMLFile(); 
      PopulateDDL2FromXMLFile(); 
     } 

     private void button1_Click(object sender, RoutedEventArgs e) 
     { 
      var x = XElement.Load(@"C:\Work\ANTScripts_Check_IN.xml"); 
      if (comboBox1.SelectedIndex == 0 && comboBox2.SelectedIndex == 0) 
      { 
       var xElement = x.Element("buildmachine4").Element("checkout1"); 
       var p = new Process 
       { 
        StartInfo = new ProcessStartInfo(xElement.Attribute("exe").Value, xElement.Attribute("folder").Value) 
       }; 
       p.Start(); 
      } 
      if (comboBox1.SelectedIndex == 0 && comboBox2.SelectedIndex == 1) 
      { 
       var xElement = x.Element("buildmachine4").Element("checkout2"); 
       var p = new Process 
       { 
        StartInfo = new ProcessStartInfo(xElement.Attribute("exe").Value, xElement.Attribute("folder").Value) 
       }; 
       p.Start(); 
      } 
     } 
     public void PopulateDDL1FromXMLFile() 
     { 
      ds.Clear(); 
      ds.ReadXml(@"C:\GUI\buildermanageremail.xml"); 

      DataView dv = ds.Tables["buildmachine"].DefaultView; 

      comboBox1.ItemsSource = dv; //Sets the collection of items from which to populate 
      comboBox1.DisplayMemberPath = "value"; //Sets the path within an item to use for display 
     } 
     public void PopulateDDL2FromXMLFile() 
     { 
      ds1.Clear(); 
      ds1.ReadXml(@"C:\GUI\buildermanageremail.xml"); 

      DataView dw = ds.Tables["buildstream"].DefaultView; 

      comboBox2.ItemsSource = dw; //Sets the collection of items from which to populate 
      comboBox2.DisplayMemberPath = "value"; //Sets the path within an item to use for display 
     } 
    } 
} 

buildermanageremail.xml:

<?xml version="1.0" encoding="utf-8"?> 
<xml> 
    <builderemail> 
      <builder> 
       <value>[email protected]</value> 
      </builder> 
      <builder> 
       <value>Others</value> 
      </builder> 
      <builder> 
       <value>[email protected]</value> 
      </builder> 
    </builderemail> 
    <manageremail> 
      <manager> 
       <value>[email protected]</value> 
      </manager> 
      <manager> 
       <value>Others</value> 
      </manager> 
      <manager> 
      <value>[email protected]</value> 
      </manager> 
    </manageremail> 
    <build> 
      <buildmachine> 
       <value>4</value> 
      </buildmachine> 
      <buildmachine> 
       <value>5</value> 
      </buildmachine> 
      <buildstream> 
        <value>6.70</value> 
      </buildstream> 
      <buildstream> 
        <value>6.80</value> 
      </buildstream> 
    </build>   
</xml> 

ANTScripts_Check_In.xml:

<buildmachine4> 
    <checkout1 exe="wco" folder='-f -R "C:/Work/6.70/ANT Builds/"'/> 
    <checkout2 exe="wco" folder='-f -R "C:/Work/6.80/ANT Builds/"'/>  
</buildmachine4> 
<buildmachine5> 
    <checkout3 exe="wco" folder='-f -R "C:/Work/7.00/ANT Builds/"'/> 
</buildmachine5> 

我的問題是:當這些XML文件進行編輯,會發生什麼和用戶新的元素,將它們添加例如,如果我有buildstream 7.10我想補充一點7.10手動作爲新元素。路徑也一樣。它不會工作,因爲我在我的GUI中對這些進行了硬編碼。例如:

if (comboBox1.SelectedIndex == 0 && comboBox2.SelectedIndex == 0) 

因此,應該做些什麼來解決這個問題?我不想觸摸我的代碼,而只是編輯xml文件。

編輯1: 您的信息,如果我選擇buildmachine 4組合框1,我得到在組合框中2

選擇6.70或6.80的選擇,如果我選擇combobox1 buildmachine 5,我得到的選項在組合框中選擇2 7.00

要簡單地說,我需要修改我的代碼,我不總是要回來,改變我的代碼,以滿足我的需要(改變XML文件)。

例如,如果我有一個新的版本流7.10和我與它相關聯的新路徑會發生什麼?

讓我們舉例來說,如果選擇combobox2 6.70,相關聯的路徑是C:/Work/6.70/ANT構建/

6.80相關聯的路徑是C:/Work/6.80/ANT構建/

7.00相關的路徑是C:/Work/7.00/ANT構建/

7.10關聯路徑是C:/Work/7.10/ANT構建/

我的新的XML文件是這樣的:

buildermanageremail.xml

 <?xml version="1.0" encoding="utf-8"?> 
      <xml> 
       <builderemail> 
         <builder> 
          <value>[email protected]</value> 
         </builder> 
         <builder> 
          <value>Others</value> 
         </builder> 
         <builder> 
          <value>[email protected]</value> 
         </builder> 
       </builderemail> 
       <manageremail> 
         <manager> 
          <value>[email protected]</value> 
         </manager> 
         <manager> 
          <value>Others</value> 
         </manager> 
         <manager> 
         <value>[email protected]</value> 
         </manager> 
       </manageremail> 
       <build> 
         <buildmachine> 
          <value>4</value> 
         </buildmachine> 
         <buildmachine> 
          <value>5</value> 
         </buildmachine> 
         <buildstream> 
          <value>6.70</value> 
         </buildstream> 
         <buildstream> 
          <value>6.80</value> 
         </buildstream> 
          <buildstream> 
          <value>7.00</value> 
         </buildstream> 
          <buildstream> 
          <value>7.10</value> 
         </buildstream> 
       </build>   
      </xml> 

新antscript_checkin.xml

<buildmachine4> 
    <checkout1 exe="wco" folder='-f -R "C:/Work/6.70/ANT Builds/"'/> 
    <checkout2 exe="wco" folder='-f -R "C:/Work/6.80/ANT Builds/"'/>  
</buildmachine4> 
<buildmachine5> 
    <checkout3 exe="wco" folder='-f -R "C:/Work/7.00/ANT Builds/"'/> 
    <checkout4 exe="wco" folder='-f -R "C:/Work/7.10/ANT Builds/"'/> 
</buildmachine5> 
+0

我會說,如果代碼難以鏈接到數據文件(xml),那麼你只做兩件事:不要觸摸硬連接的數據部分,更改代碼以接受數據文件中的更改。 – VikciaR 2011-04-15 07:09:01

+0

是否可以修復我的代碼並接受數據文件中的所有其他更改? – jeremychan 2011-04-15 07:11:07

+0

如果我理解正確,您可以硬編碼combobox1內容。使其變爲動態並從xml文件中填充它,然後您總是可以動態添加新值。 – VikciaR 2011-04-15 07:25:09

回答

1

您已經綁定的組合框讓你獲得建造機器,並從他們的buildstream。根據選定的值,你可以查找什麼來構建這樣的:

var x = XElement.Load(@"C:\Work\ANTScripts_Check_IN.xml"); 
var machine = comboBox1.SelectedValue; 
var buildStream = comboBox2.SelectedValue; 

var xElement = x.Element("buildmachine" + machine).Elements().First(el => el.Attributes().Any(a => a.Value.Contains(buildStream))); 
var p = new Process 
{ 
    StartInfo = new ProcessStartInfo(xElement.Attribute("exe").Value, xElement.Attribute("folder").Value) 
}; 
p.Start(); 

我沒有運行代碼,但思路應該是清楚的。

+0

得到了錯誤\t'System.Collections.Generic.IEnumerable '不包含'Find'的定義,也沒有包含接受'System.Collections'類型的第一個參數的擴展方法'Find'。可找到Generic.IEnumerable '(您是否缺少使用指令或程序集引用?) – jeremychan 2011-04-15 08:09:03

+0

錯誤名爲'e'的局部變量無法在此範圍內聲明,因爲它會給'e'賦予不同的含義,'e'已經在'父'或'當前'範圍內用於表示別的東西 – jeremychan 2011-04-15 08:09:22

+0

我重命名了變量,並且您需要'使用System.Linq' – ChrisWue 2011-04-15 08:12:28

0

如果用戶選擇行,其中value爲「4」,並且buildstream行的value爲「6」。80" 你要開始運行使用中的信息checkout元素buildmachine4元素,其folder屬性包含字符串下一個過程‘6.80’那是正確的

如果是的話,這應該做的伎倆:

string buildmachine = comboBox1.SelectedValue as string; 
string buildstream = comboBox2.SelectedValue as string; 
string xpath = string.Format("//buildmachine{0}/*[contains(@folder, '/{1}/')]", 
    buildmachine, buildstream); 

...其中,在上面的例子中,將設置xpath到:

//buildmachine4/*[contains(@folder, '/6.80/')] 

假設您已經加載了第二個XML文檔爲XDocument,Y那麼您可以同時找到正是如此的元素:

XElement elm = d.XPathSelectElement(xpath); 

有兩點需要注意:

1)在contains功能斜線讓XPath的方式保持它從錯誤的元件匹配,如果您有版本的「6.80」和「6.80.1」,因爲該模式實際上是在尋找「/6.80/」。

2)如果在buildmachineX元素下還有folder屬性的其他元素,則可能需要在XPath中指定其名稱。在這種情況下,由於*比賽,不論其名稱中的所有元素,你需要改變謂語表明名稱爲好,如:

*[starts-with(name(), 'checkout') and contains(@folder, '/6.80/')] 

3)當然,你可以找到一個元素Linq表達式太多,例如:

XElement elm = d.Descendants("buildmachine" + buildmachine) 
        .Elements() 
        .Where(x => x.Name.StartsWith("checkout") && 
           x.Attribute("folder").Value.IndexOf("/" + buildstream + "/") >= 0) 
        .First(); 

我發現XPath更容易處理,我自己。