从某个元素向前读取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>
感谢您的帮助。
试试这个(假设你说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;
}
}