如何使用行号C#在XML文件中查找节点?

时间:2016-06-23 03:34:38

标签: c# asp.net xml xpath

我有以下XML文件。当我在Process中使用它时,它会给我一些错误,如

  

[2016-06-22 19:29:53 IST]错误:“第15行第20列:元素”电子“的字符内容无效;必须等于XPath中的”食物“,”商品“或”手机“   /产品/产品[1] / ITEM_TYPE“

此XPath /products/product[1]不正确。它是由他们的系统返回的。 所以,我必须搜索它并通过Line No替换原始值。

Order.xml

<products>
    <product>
        <country>AE</country>
        <sale>false</sale>
        <item_type>foods</item_type>
    </product>
    <product>
        <country>IN</country>
        <sale>false</sale>
        <item_type>goods</item_type>
    </product>
    <product>
        <country>US</country>
        <sale>false</sale>
        <item_type>electronics</item_type>
    </product>
    <product>
        <country>AM</country>
        <sale>false</sale>
        <item_type>mobiles</item_type>
    </product>
</products>

请告诉我使用XML文档中的第(15)行进行搜索

4 个答案:

答案 0 :(得分:2)

处理xml时,不应该依赖行/ colmns数字。 Xml并不关心空格,格式化只是方便可读性;尽管在您的示例中已正确报告,但我不相信它将来会一直这样。间隔xpath也是不正确的,但暂时不要纠缠于此。

您需要收回对问题的控制权...您应该创建自己的验证读取器并在解析xml时捕获验证错误。如何执行此操作取决于您使用的框架。 XmlValidatingReader或XmlReader以及相应的XmlReaderSettings。 您可以设置回调/事件处理程序以在读取xml文件时捕获错误,这样您就可以确定您在正确的位置并获得处理错误所需的所有信息。使用XmlReader还可以让您继续处理整个文件,而不仅仅是在第一次出错时停止。

代码对于SO而言太大了,我们需要您提供更多信息,但谷歌搜索会找到很多例子,包括来自microsoft的这个例子:https://msdn.microsoft.com/en-us/library/w5aahf2a(v=vs.100).aspx

  1. 构造一个新的XmlReaderSettings实例。

  2. 将XML架构添加到XmlReaderSettings实例的Schemas属性中。

  3. 将Schema指定为ValidationType。

  4. 指定ValidationFlags和ValidationEventHandler来处理验证期间遇到的架构验证错误和警告。

  5. 将XmlReaderSettings对象与XML文档一起传递给XmlReader类的Create方法,创建一个模式验证XmlReader。

  6. 调用Read()从头到尾运行xml。

答案 1 :(得分:0)

这对你有用吗?

string[] lines = File.ReadAllLines(@"C:\order.xml", Encoding.UTF8);
var line15 = lines[14];

答案 2 :(得分:0)

XmlDocument doc = new XmlDocument();
doc.Load(@"C:\order.xml");
XmlElement el =(XmlElement)doc.SelectSingleNode("/products/product[1]/item_type");
if(el != null) { el.ParentNode.RemoveChild(el); }

你可以使用上面的代码删除节点...使用适当的Xpath你可以删除所有不等于食物,好或移动的item_type。

答案 3 :(得分:0)

试试这个,

var xml = XDocument.Load(@"C:\order.xml", LoadOptions.SetLineInfo);
var lineNumbers = xml.Descendants()
                     .Where(x => !x.Descendants().Any() && //exact node contains the value
                                  x.Value.Contains("foods"))
                     .Cast<IXmlLineInfo>()
                     .Select(x => x.LineNumber);
int getLineNumber = lineNumbers.First();