xml解析需要帮助解决xml文件是否被手动编辑

xml解析需要帮助解决xml文件是否被手动编辑

问题描述:

你好,我的代码如下。我用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

您已经绑定的组合框让你获得建造机器,并从他们的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

如果用户选择行,其中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更容易处理,我自己。