在没有标签名称时使用 Linq 解析 xml 到 xml

Parse xml using Linq to xml when there's no tag name

我有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>

I can't change that xml file. I know there must be column names instead of text tag but it's not written by me

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 个标签(根据这条语句猜对了 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 展平序列并获取数据。