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

本文关键字:读取 XML 节点 元素 | 更新日期: 2023-09-27 17:59:21

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

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

1) 查找标签npid的第一个实例,带有文本要查找的文本

2) 提取节点NodeToExtract并将其存储在某个数据对象中。有几个节点被称为NodeToExtract,但我只想在最初搜索文本后找到第一个text以查找

<?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>

感谢您的帮助。

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

试试这个(假设你说NodeToExtract是指mi元素):

    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());

真正的问题是,如果没有暴力,就无法做到这一点。可以提取有问题的节点,然后将其加载到xml文档中

例如:

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;
    }
}