【问题标题】:Parse xml using Linq to xml when there's no tag name没有标签名称时使用 Linq to xml 解析 xml
【发布时间】:2015-12-07 05:40:16
【问题描述】:

我有 xml。我正在使用此代码检索信息:

 XNamespace ns = "urn:schemas-microsoft-com:office:excel";
            var xdoc = XDocument.Load(@"path");

            IEnumerable<string> ss = xdoc.Descendants(ns + "Crn")
                                         .Elements(ns + "Text")
                                         .Select(x => (string)x);




            using (System.IO.StreamWriter file =
            new System.IO.StreamWriter(@"path", true))
            {
                foreach (var x in ss)
                {
                    file.WriteLine(x);
                }
            }

但我只想检索 last - 1 标记文本。我在那里添加了文本“this text”。我怎样才能做到这一点? 如果我在 .Element 之后添加.LastOrDefault() 会引发错误..

这是我的 XML

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40">
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<SupBook>
<Xct>
<Crn>
          <Row>9</Row>
          <ColFirst>1</ColFirst>
          <ColLast>3</ColLast>
          <Text>02</Text>
          <Text>this text</Text>
          <Text>asd</Text>
        </Crn>
        <Crn>
          <Row>10</Row>
          <ColFirst>1</ColFirst>
          <ColLast>3</ColLast>
          <Number>25</Number>
          <Text>this text</Text>
          <Text>asd</Text>
        </Crn>
        <Crn>
          <Row>11</Row>
          <ColFirst>1</ColFirst>
          <ColLast>3</ColLast>
          <Number>62</Number>
          <Text>this text</Text>
          <Text>asd</Text>
        </Crn>
 </Xct>
    </SupBook>
  </ExcelWorkbook>
</Workbook>

我无法更改该 xml 文件。我知道必须有列名 而不是文本标签,但不是我写的

【问题讨论】:

    标签: c# xml linq linq-to-xml


    【解决方案1】:

    我猜你正在寻找最后但 1 个标签(通过此语句 I've added there text "this text". 猜测它)。

    这应该会给你预期的结果:-

    IEnumerable<string> ss = xdoc.Descendants(ns + "Crn")
              .Select(x => x.Elements(ns + "Text").Reverse().Skip(1).Take(1).DefaultIfEmpty())
              .SelectMany(x => x)
              .Select(x => (string)x);
    

    解释:-

    您可以首先使用Select 投影所有Text 节点。在此之后,您可以反转序列跳过 1 个元素并获取 1 个元素。为了安全起见,我添加了DefaultIfEmpty,以防只有 1 个元素。最后使用SelectMany 将序列展平并获取数据。

    【讨论】:

      【解决方案2】:
      var ss = xml.Descendants(ns + "Crn")
          .Select(x =>
          {
              var a = x.Elements(ns + "Text").ToArray();
              return a.Length > 1 ? a[a.Length - 2].Value : "";
          });
      

      应该这样做:)

      现在获得倒数第二个;)

      【讨论】:

      • 这是最后一个,不是最后一个 - 1.
      • AHHH I C :D 让我修复
      • 虽然现在正确,但接受的答案更加优雅和 linq 风格。
      猜你喜欢
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多