查找特定的xml元素内容

时间:2013-06-03 08:56:44

标签: c# linq-to-xml

我有一个大的xml文件,我希望通过给出父子元素值来获取子元素值,我是xml文件中的新东西,请在这里帮助我的xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<masterController>   <uuid>XXXXXXXXXXXXXXXXXXXXXXXXX</uuid>  
<channels>
    <channel>
      <nodeGroups>
        <nodeGroup>
          <analogNode>
            <typeCode>8</typeCode>
            <id>1</id>
            <sdos>
              <sdo>
                <description>Host ID</description>
                <compareLevel>Ignore</compareLevel>
                <datafield xmlns:xsi="http://www.XXXXX.XXXX/XXXXX/XMLSchema-instance"
xsi:type="intField">
                  <description>Host ID</description>
                  <compareLevel>Ignore</compareLevel>
                  <offset>2</offset>
                  <size>1</size>
                  <readonly>true</readonly>
                  <isMappedToPdo>false</isMappedToPdo>
                  <ownerNodeSerial>12102904</ownerNodeSerial>
                  <ownerSdoIndex>3</ownerSdoIndex>
                  <data xsi:type="intData">
                    <value xmlns:xs="http://www.XX.CC/2XXX/XMLSchema" xsi:type="xs:int">2</value>
                    <unit></unit>
                    <min>1</min>
                    <max>15</max>
                  </data>
                  <intValue>2</intValue>
                </datafield>
                <index>3</index>
                <totalbytes>3</totalbytes>
              </sdo>
              <sdo>
                <description>Host ID</description>
                <compareLevel>Ignore</compareLevel>
                <datafield xmlns:xsi="http://www.XXXXX.XXXX/XXXXX/XMLSchema-instance"
xsi:type="intField">
                  <description>Host ID</description>
                  <compareLevel>Ignore</compareLevel>
                  <offset>2</offset>
                  <size>1</size>
                  <readonly>true</readonly>
                  <isMappedToPdo>false</isMappedToPdo>
                  <ownerNodeSerial>12102905</ownerNodeSerial>
                  <ownerSdoIndex>4</ownerSdoIndex>
                  <data xsi:type="intData">
                    <value xmlns:xs="http://www.XX.CC/2XXX/XMLSchema" xsi:type="xs:int">16</value>
                    <unit></unit>
                    <min>1</min>
                    <max>15</max>
                  </data>
                  <intValue>2</intValue>
                </datafield>
                <index>3</index>
                <totalbytes>3</totalbytes>
              </sdo>
            </sdos>
          </analogNode>
        </nodeGroup>
      </nodeGroups>
    </channel>   </channels> </masterController>

我正在尝试这个,但我没有做任何事情:

XElement root = XElement.Load(Server.MapPath("sample.xml"));

              IEnumerable<XElement> masterco = from el in root.Elements("sdo") where (from add in   el.Elements("datafield")

                     where
                         (string)add.Element("ownerNodeSerial") == TextBox1.Text &&

                         (string)add.Element("ownerSdoIndex") == TextBox1.Text

                     select add)

                    .Any()
                  select el;
              foreach (XElement el in masterco)
              {

                TextBox3.Text = (string)el.Element("value");
              }

我想得到这个:

 <value xmlns:xs="http://www.XX.CC/2XXX/XMLSchema" xsi:type="xs:int">16</value>

并能够更新它。

1 个答案:

答案 0 :(得分:1)

您的查询中存在一个主要错误:

您在Elements上使用root,但您正在寻找不是根标记的直接子标记sdo的标记。您必须改为使用Descendants

此外,我认为您想要OR而不是AND关于TextBox1的文字。

修复它:

var masterco = from el in root.Descendants("sdo")
               where (from add in   el.Elements("datafield")
                      where
                          (string)add.Element("ownerNodeSerial") == TextBox1.Text ||
                          (string)add.Element("ownerSdoIndex") == TextBox1.Text
                       select add).Any()
               select el;

要实际获得所需的值,您应该使用不同的查询。根本不需要选择sdo标记。

var value = root.Descendants("datafield")
                .Where(x => (string)x.Element("ownerNodeSerial") == TextBox1.Text ||
                            (string)x.Element("ownerSdoIndex") == TextBox1.Text)
                .Select(x => (string)x.Element("data").Element("value"))
                .Single();

TextBox3.Text = value;

您可以看到我假设在整个XML文档中只存在一个匹配的datafield/data/value条目。我从您更新文本框的方式中获取该信息。如果存在多个标签,这将毫无意义 - 值将在文本框中相互覆盖。