当没有标记名称时,使用Linq将xml解析为xml

时间:2015-12-07 05:40:16

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

我有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文件。我知道必须有列名   而不是文本标签,但它不是我写的

2 个答案:

答案 0 :(得分:2)

我猜你正在寻找最后但只有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);

<强>解释: -

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

答案 1 :(得分:0)

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

应该这样做:)

现在获得倒数第二个;)