C# 从某个元素向前读取XML节点?

C# 从某个元素向前读取XML节点?,c#,.net,visual-studio-2010,linq,linq-to-xml,C#,.net,Visual Studio 2010,Linq,Linq To Xml,我知道有很多方法可以做到这一点,但我正在寻找一种最简单的方法,而不必使用streamreader或其他更为手动的工具,这将迫使我遍历整个文件并比较无尽的字符串。一种可能是使用streamreader查找特定文本,然后使用一些XML库检索节点 这是我的XML。这就是我需要做的: 1使用要查找的文本查找标记npid的第一个实例 2提取节点提取并存储在某个数据对象中。有几个节点称为NodeToExtract,但我只希望在初始搜索文本后找到第一个节点 感谢您的帮助。真正的问题是,没有暴力是无法做到这一点

我知道有很多方法可以做到这一点,但我正在寻找一种最简单的方法,而不必使用streamreader或其他更为手动的工具,这将迫使我遍历整个文件并比较无尽的字符串。一种可能是使用streamreader查找特定文本,然后使用一些XML库检索节点

这是我的XML。这就是我需要做的:

1使用要查找的文本查找标记npid的第一个实例

2提取节点提取并存储在某个数据对象中。有几个节点称为NodeToExtract,但我只希望在初始搜索文本后找到第一个节点


感谢您的帮助。

真正的问题是,没有暴力是无法做到这一点的。可以提取相关节点,然后将其加载到xmldocument中

例如:

class Program
{
    static void Main(string[] args)
    {
        string buffer = " blah blah blah " +
            "<nw>" +
            "<npid>Text to Find</npid>" +
            "<r>0</r>" +
            "</nw>" +
            "</mi>" +
            "</ne>" +
            "<ne>" +
            "<ofid>" +
            "<ofun>ABC</ofun>" +
            "<ofdn>Blah</ofdn>" +
            "<ofsw>18R</ofsw>" +
            "</ofid>" +
            "<mi>" +
            "<mts>Good stuff</mts>" +
            "<gp>000</gp>" +
            "<mu>Value1</mu>" +
            "<mu>Value2</mu>" +
            "<mu>Value3</mu>" +
            "<mu>Value4</mu>" +
            "<mu>Value5</mu>" +
            "<nw>" +
            "<npid>ABC1221</npid>" +
            "<r>99</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "</nw>" +
            "<nw>" +
            "<npid>ABC1222</npid>" +
            "<r>99</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "</nw>" +
            "<nw>" +
            "<npid>ABC1223</npid>" +
            "<r>99</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "</nw>" +
            "</mi> blah blah blah";

        int indexOf_Text = buffer.IndexOf( "Text to Find" );

        XmlDocument nextMiNode = ExtractNode( indexOf_Text, buffer );

        // now traverse the node as you please
        foreach ( XmlNode node in nextMiNode.ChildNodes[1].ChildNodes )
        {
            if ( node.Name == "mts" )
            {
                // Good stuff ?
                if ( node.InnerText == "Good stuff" )
                    Console.WriteLine( node.InnerText );
            }
        }
        Console.ReadKey();
    }

    static XmlDocument ExtractNode(int indexOf_Text, string buffer)
    {
        XmlDocument xDoc = new XmlDocument();
        StringBuilder sbNode = new StringBuilder();
        sbNode.Append( "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" );
        bool inNode = false;
        for ( int i = indexOf_Text; i < buffer.Length - 1; i++ )
        {
            // find the first "<mi>" tag ..
            if ( !inNode &&
                ( buffer[i] == '<' &&
                  i + 3 < buffer.Length - 1 &&
                  buffer[i + 1] == 'm' &&
                  buffer[i + 2] == 'i' &&
                  buffer[i + 3] == '>' ) )
                inNode = true;

            if ( inNode ) // capture it
                sbNode.Append( buffer[i] );

            // find the next "<mi/>" ending tag (only if we found the begining tag : inNode=true)
            if ( inNode &&
                ( buffer[i] == '>' &&
                  i - 4 >= indexOf_Text &&
                  buffer[i - 1] == 'i' &&
                  buffer[i - 2] == 'm' &&
                  buffer[i - 3] == '/' &&
                  buffer[i - 4] == '<' ) )
            {
                break; // we are done
            }
        }
        xDoc.LoadXml( sbNode.ToString() );
        return xDoc;
    }
} 

假设您的意思是mi元素,请尝试这样说,NodeToExtract:

使现代化
您的XML格式不正确,没有可查找的属性文本。ReadSubTree方法就是您想要的方法,我想……我刚知道有人会用您的XML格式不正确进行回复。为了消除混淆,XML文件是400K;我不能发布整个文件,现在可以吗?正如我在帖子中提到的,在14500行中,这一部分是我最感兴趣的。最后,我写错了:有一个名为npid的标记,要查找文本。您现在看到了吗?为了分析XML的结构,您至少需要工作良好的XML片段。请发布一个格式良好的最小示例。我添加了一个格式良好的XML块。效果非常好。最后一件事,您知道如何将query2.First移动到数据集或数据表中吗?谢谢。我最终使用它将结果字符串复制到一个数据集:StringReader stream=null;XmlTextReader=null;数据集xmlDS=新数据集;stream=新的StringReaderxml;reader=新的XmlTextReaderstream;xmlDS.ReadXmlreader;谢谢问题是我会手动解析它,这正是我想要避免的。
class Program
{
    static void Main(string[] args)
    {
        string buffer = " blah blah blah " +
            "<nw>" +
            "<npid>Text to Find</npid>" +
            "<r>0</r>" +
            "</nw>" +
            "</mi>" +
            "</ne>" +
            "<ne>" +
            "<ofid>" +
            "<ofun>ABC</ofun>" +
            "<ofdn>Blah</ofdn>" +
            "<ofsw>18R</ofsw>" +
            "</ofid>" +
            "<mi>" +
            "<mts>Good stuff</mts>" +
            "<gp>000</gp>" +
            "<mu>Value1</mu>" +
            "<mu>Value2</mu>" +
            "<mu>Value3</mu>" +
            "<mu>Value4</mu>" +
            "<mu>Value5</mu>" +
            "<nw>" +
            "<npid>ABC1221</npid>" +
            "<r>99</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "</nw>" +
            "<nw>" +
            "<npid>ABC1222</npid>" +
            "<r>99</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "</nw>" +
            "<nw>" +
            "<npid>ABC1223</npid>" +
            "<r>99</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "<r>0</r>" +
            "</nw>" +
            "</mi> blah blah blah";

        int indexOf_Text = buffer.IndexOf( "Text to Find" );

        XmlDocument nextMiNode = ExtractNode( indexOf_Text, buffer );

        // now traverse the node as you please
        foreach ( XmlNode node in nextMiNode.ChildNodes[1].ChildNodes )
        {
            if ( node.Name == "mts" )
            {
                // Good stuff ?
                if ( node.InnerText == "Good stuff" )
                    Console.WriteLine( node.InnerText );
            }
        }
        Console.ReadKey();
    }

    static XmlDocument ExtractNode(int indexOf_Text, string buffer)
    {
        XmlDocument xDoc = new XmlDocument();
        StringBuilder sbNode = new StringBuilder();
        sbNode.Append( "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" );
        bool inNode = false;
        for ( int i = indexOf_Text; i < buffer.Length - 1; i++ )
        {
            // find the first "<mi>" tag ..
            if ( !inNode &&
                ( buffer[i] == '<' &&
                  i + 3 < buffer.Length - 1 &&
                  buffer[i + 1] == 'm' &&
                  buffer[i + 2] == 'i' &&
                  buffer[i + 3] == '>' ) )
                inNode = true;

            if ( inNode ) // capture it
                sbNode.Append( buffer[i] );

            // find the next "<mi/>" ending tag (only if we found the begining tag : inNode=true)
            if ( inNode &&
                ( buffer[i] == '>' &&
                  i - 4 >= indexOf_Text &&
                  buffer[i - 1] == 'i' &&
                  buffer[i - 2] == 'm' &&
                  buffer[i - 3] == '/' &&
                  buffer[i - 4] == '<' ) )
            {
                break; // we are done
            }
        }
        xDoc.LoadXml( sbNode.ToString() );
        return xDoc;
    }
} 
    XElement doc = XElement.Parse(@"<?xml version=""1.0"" encoding=""ISO-8859-1""?><mdc><ne><neun>ADB</neun><nn>SubNetwork=Context</nn><nw>R33</nw><mi><nut>20140101</nut><hq>000</hq><nw><npid>Text to Find</npid><r>0</r></nw></mi></ne><ofid><ofun>ABC</ofun><ofdn>Blah</ofdn><ofsw>18R</ofsw></ofid><mi><mts>More Blah</mts><gp>000</gp><mu>Value1</mu><mu>Value2</mu><mu>Value3</mu><mu>Value4</mu><mu>Value5</mu><nw><npid>ABC1221</npid><r>99</r><r>0</r><r>0</r><r>0</r><r>0</r></nw><nw><npid>ABC1222</npid><r>99</r><r>0</r><r>0</r><r>0</r><r>0</r></nw><nw><npid>ABC1223</npid><r>99</r><r>0</r><r>0</r><r>0</r><r>0</r></nw></mi></mdc>");
    IEnumerable<XElement> query1 = doc.Descendants("npid").Where(c => c.Value == "Text to Find").Ancestors("mi");
    IEnumerable<XElement> query2 = query1.First().Parent.ElementsAfterSelf("mi");
    dynamic resut_node = new XElement("result");
    resut_node.Add(query1.First());
    resut_node.Add(query2.First());
    Console.Write(resut_node.ToString());
XElement doc = XElement.Parse(@"<?xml version=""1.0"" encoding=""ISO-8859-1""?>
                                                <mdc>
                                                    <ne>
                                                        <neun>ADB</neun>
                                                        <nn>SubNetwork=Context</nn>
                                                        <nw>R33</nw>
                                                        <mi>
                                                            <nut>20140101</nut>
                                                            <hq>000</hq>
                                                            <nw>
                                                                <npid>Text to Find</npid>
                                                                <r>0</r>
                                                            </nw>
                                                        </mi>
                                                    </ne>
                                                    <ofid>
                                                        <ofun>ABC</ofun>
                                                        <ofdn>Blah</ofdn>
                                                        <ofsw>18R</ofsw>
                                                    </ofid>
                                                    <NodeToExtract>
                                                        <mts>More Blah</mts>
                                                        <gp>000</gp>
                                                        <mu>Value1</mu>
                                                        <mu>Value2</mu>
                                                        <mu>Value3</mu>
                                                        <mu>Value4</mu>
                                                        <mu>Value5</mu>
                                                        <nw>
                                                            <npid>ABC1221</npid>
                                                            <r>99</r>
                                                            <r>0</r>
                                                            <r>0</r>
                                                            <r>0</r>
                                                            <r>0</r>
                                                        </nw>
                                                        <nw>
                                                            <npid>ABC1222</npid>
                                                            <r>99</r>
                                                            <r>0</r>
                                                            <r>0</r>
                                                            <r>0</r>
                                                            <r>0</r>
                                                        </nw>
                                                        <nw>
                                                            <npid>ABC1223</npid>
                                                            <r>99</r>
                                                            <r>0</r>
                                                            <r>0</r>
                                                            <r>0</r>
                                                            <r>0</r>
                                                        </nw>
                                                    </NodeToExtract>
                                                </mdc>");

            IEnumerable<XElement> query1 = doc.Descendants("npid").Where(c => c.Value == "Text to Find").Ancestors("mi");
            IEnumerable<XElement> query2 = query1.First().Parent.ElementsAfterSelf("NodeToExtract");

            Console.Write(query2.First().ToString());