在 C# 中查询 XML 元素

Querying XMLelements in C#

我有很多复杂的 XML 文件,我想查询和搜索这些文件以获得一个值,下面是两个缩短的示例:

1

<textInfo>
 <freeText>
  <informationType>15</informationType>
 </freeText>
</textInfo>
<textInfo>
 <freeText>
  <textSubject>4</textSubject>
  <informationType>47</informationType>
 </freeText>
  <freeText>My required text</freeText>
</textInfo>
<textInfo>
 <freeText>
  <informationType>733</informationType>
  <status>1</status>
 </freeText>
</textInfo>

2

<textInfo>
  <freeText>
    <textSubject>4</textSubject>
    <informationType>15</informationType>
    <status>0</status>
  </freeText>
</textInfo>
<textInfo>
  <freeText>
    <textSubject>4</textSubject>
    <informationType>47</informationType>
  </freeText>
  <freeText>My required text</freeText>
</textInfo>
<textInfo>
  <freeText>
    <textSubject>4</textSubject>
    <status>0</status>
  </freeText>
</textInfo>
<textInfo>
  <freeText>
    <textSubject>4</textSubject>
    <informationType>61</informationType>
  </freeText>
</textInfo>
<textInfo>
  <freeText>
    <textSubject>4</textSubject>
    <informationType>39</informationType>
  </freeText>
  <freeText>some text</freeText>
  <freeText>some other text</freeText>
</textInfo>

要求的输出是: 标签 <freeText> 内的文本(我需要的文本),其中标签 <informationType> = (47)

已经尝试了多个 linq to xml 代码,但其中 none 对我有用。 例如

代码1

var query = from q in XDocument.Parse(requestInterceptor.LastResponseXML)
    .Descendants("freeText")
    where (bool)q.Element("informationType").Equals("47")
    select q.Element("freeText").Value;

代码2

XDocument doc = XDocument.Parse(requestInterceptor.LastResponseXML); ;
    var q = doc
    .Descendants("freeText[1]")
    .Where(ft => ((int?)ft.Element("informationType")) == 47);
Object.Type = q.ToString();

代码3

XmlDocument doc = new XmlDocument();
                    doc.LoadXml(requestInterceptor.LastResponseXML);

                    foreach (XmlNode node in doc.DocumentElement.SelectSingleNode("//textInfo/freeText[informationType>=47]/informationType"))
                    {
                        Object.Type = node.InnerText;
                    }

代码4

XmlDocument doc2 = new XmlDocument();
                    doc.LoadXml(requestInterceptor.LastResponseXML);
                    foreach (XmlNode node in doc2.SelectNodes("//textInfo/freeText[informationType>=47]/informationType"))
                    {
                        Object.Type = node.InnerText;
                    }

注意:我只从网络服务中获取 xml。我不会将它存储在某处或作为 xml 文件。另请注意,这是 xml 的一部分,只有我需要获取信息

您需要获取 selected freeText 元素的兄弟元素。 您可以使用具有适当名称空间的 XPATH 查询:

var doc = new XmlDocument(); doc.LoadXml(XMLfile); 
var xmlns = new XmlNamespaceManager(doc.NameTable); 
xmlns.AddNamespace("ns", "your_namespace"); 
var res = doc.SelectSingleNode("//ns:textInfo/ns:freeText[ns:informationType='47']/following-sibling::ns:freeText", xmlns);     
Console.Write(res.InnerText);

输出:

我需要的文字

更新(如评论中要求):

Sibling node is the node immediately following the selected node in the same tree level.

第二个例子:

<textInfo>
  <freeText>
    <textSubject>4</textSubject>
    <informationType>47</informationType>
  </freeText>
  <freeText>My required text</freeText>
</textInfo>

上面的代码正在执行以下操作:

  1. 选择 informationType 等于 47 的第一个 freeText 节点。
  2. select freeText 的第一个兄弟节点,是带有 "My required text"
  3. 的自由文本

您可以尝试以下方法(我只是假设您有根元素,否则它对您不起作用。

Check fiddle here

    string input = @"<root>
        <textInfo>
            <freeText>
                <informationType>15</informationType>
            </freeText>
        </textInfo>
        <textInfo>
            <freeText>
                <textSubject>4</textSubject>
                <informationType>47</informationType>
            </freeText>
            <freeText>My required text</freeText>
        </textInfo>
        <textInfo>
            <freeText>
                <informationType>733</informationType>
                <status>1</status>
            </freeText>
        </textInfo>
    </root>";

    var doc = XDocument.Parse(input);


    var freeTexts = doc.Descendants("textInfo")
        .Where(tf => tf.Element("freeText").Element("informationType") != null &&
               tf.Element("freeText").Element("informationType").Value.Equals("47") &&
               tf.Elements("freeText").Count() > 1)
        .Select(tf => tf.Elements("freeText").Skip(1).Single().Value).ToList();