嵌套的XPath迭代可能吗?

时间:2011-03-14 14:49:07

标签: c# xml xpath nested iteration

我有一个像这样的XML文件模板来自某些IC芯片,我希望能够将每个Pins Test类型数据存储为数组,以便稍后我可以在笛卡尔图上绘制它。

数据结构如下: <NUMBER></NUMBER>是IC特定引脚的名称 <Curve Count="">是对引脚进行的测试次数 <Type></Type>是测试类型

并且我必须将一些电压值和电流值放入一个数组中,以便稍后使用。

反正!我的问题是如何获得这些价值?我没有要求直接回答(但它是适当的)但是一些让我找到该主题的指南非常适合。

编辑:如果somone请给我一个代码,从A1获得3个电压和3个电流值,我可以很容易地得到这个想法并继续自己。

这个XML看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<Document>
  <Device>NEC555</Device>
  <Pins Count="3">
    <Pin>
      <Number>A1</Number>
      <Curves Count ="3">
        <Curve>
          <Type>PreStress</Type>
          <VIPairs Count="3">
            <VIPair>
              <Voltage>-2</Voltage>
              <Current>-0.003</Current>
            </VIPair>
            <VIPair>
              <Voltage>-1</Voltage>
              <Current>-0.002</Current>
            </VIPair>
            <VIPair>
              <Voltage>-0</Voltage>
              <Current>-0.001</Current>
            </VIPair>
          </VIPairs>
        </Curve>
        <Curve>
          <Type>PreFail</Type>
          <VIPairs Count="3">
            <VIPair>
              <Voltage>-2</Voltage>
              <Current>-0.003</Current>
            </VIPair>
            <VIPair>
              <Voltage>-1</Voltage>
              <Current>-0.002</Current>
            </VIPair>
            <VIPair>
              <Voltage>-0</Voltage>
              <Current>-0.001</Current>
            </VIPair>
          </VIPairs>
        </Curve>
        <Curve>
          <Type>PostFail</Type>
          <VIPairs Count="0">
          </VIPairs>
        </Curve>
      </Curves>
    </Pin>
    <Pin>
      <Number>B1</Number>
      <Curves Count ="3">
        <Curve>
          <Type>PreStress</Type>
          <VIPairs Count="3">
            <VIPair>
              <Voltage>-3</Voltage>
              <Current>-0.005</Current>
            </VIPair>
            <VIPair>
              <Voltage>-1</Voltage>
              <Current>-0.002</Current>
            </VIPair>
            <VIPair>
              <Voltage>-0</Voltage>
              <Current>-0.001</Current>
            </VIPair>
          </VIPairs>
        </Curve>
        <Curve>
          <Type>PreFail</Type>
          <VIPairs Count="3">
            <VIPair>
              <Voltage>-3</Voltage>
              <Current>-0.003</Current>
            </VIPair>
            <VIPair>
              <Voltage>-1</Voltage>
              <Current>-0.002</Current>
            </VIPair>
            <VIPair>
              <Voltage>-0</Voltage>
              <Current>-0.001</Current>
            </VIPair>
          </VIPairs>
        </Curve>
        <Curve>
          <Type>PostFail</Type>
          <VIPairs Count="0">
          </VIPairs>
        </Curve>
      </Curves>
    </Pin>
  </Pins>
</Document>

3 个答案:

答案 0 :(得分:0)

查看XDocument

对于您的特定情况,它可能看起来像

XDocument doc = XDocument.Load("yourFilePath");

var data = (from pins in doc.Element("Pins").Descendants
            from pin in pins.Element("Pin")
            from curve in pin.Element("Curves").Element("Curve")
            from pair in curve.Element("VIPairs").Descendants.Descendants()
            select new {
                          Voltage = pair.Element("Voltage").Value(),
                          Current = pair.Element("Current").Value()
        });

该代码尚未经过测试

答案 1 :(得分:0)

您可以使用一些LINQ-to-XML,如下所示:

var doc = XDocument.Parse(xml);
var data = from pin in doc.Descendants("Pin")
            select new
            {
                Number = pin.Element("Number").Value,
                Curves =
                    from curve in pin.Element("Curves").Descendants("Curve")
                    select new
                    {
                        Type = curve.Element("Type").Value,
                        VIPairs =
                            from pair in curve.Descendants("VIPair")
                            select new
                            {
                                Voltage = pair.Element("Voltage").Value,
                                Current = pair.Element("Current").Value
                            }
                    }
            };

答案 2 :(得分:0)

就像我喜欢使用LINQ和XDocument一样,这是XPath更简单的情况。

根据您的XML,此XPath会查找具有给定VIPair的{​​{1}}元素下的所有Pin元素以及具有给定{{1的Number元素下的所有元素}}:

Curve

使用Type,获取三个电压和电流值的代码如下所示:

/Document/Device/Pins/Pin[Number='A1']/Curves/Curve[Type='PreStress']/VIPairs/VIPair

使用XDocument,代码为:

XmlDocument

除非您的文档先前已针对模式进行了验证,否则您可能希望在XPath string number = "A1"; string type = "PreStress" string xpath = string.Format( "/Document/Device/Pins/Pin[Number='{0}']/Curves/Curve[Type='{1}']/VIPairs/VIPair", number, type); foreach (XmlElement viPair in doc.SelectNodes(xpath)) { string current = viPair.SelectSingleNode("Current").Value; string voltage = viPair.SelectSingleNode("Voltage").Value; } 中进行最后一个节点测试,以便在缺少var values = doc.XPathSelectElements(xpath) .Select(x => new { Voltage = x.Element("Voltage").Value(), Current = x.Element("Current").Value() }); 元素的情况下代码不会失败其中一个子元素。 (或者,您可能实际上希望代码在发生异常时抛出异常;它实际上取决于源数据的质量。)