【问题标题】:Parsing an XML file that can be singleline or multiline解析可以是单行或多行的 XML 文件
【发布时间】:2014-01-17 11:53:07
【问题描述】:

我有一个可以单行的 XML 文件:

<webshop><item></item><item></item></webshop>

或多行:

<webshop>
    <item>
    </item>
    <item>
    </item>
</webshop>

或混合:

<webshop>
    <item></item>
    <item></item>
</webshop>

每个标签还有一个简短的变体,如&lt;webshop/&gt;&lt;item/&gt;,其中标签在一对 括号中打开和关闭。

每个标签可以出现任意次数,但&lt;item&gt;&lt;/item&gt;&lt;item/&gt; 标签只会出现在&lt;webshop&gt; ... &lt;/webshop&gt; 内。此外,整个 xml 标签层次结构比这两个标签要大得多(但我对这个问题保持简单),每个标签都可以有属性。

我正在尝试使用 c# 中的 xmlreader 解析这样的 xmlfile,但我总是遇到问题。

如果我尝试:

while(reader.ReadToFollowing("webshop"))
{
    Console.WriteLine("webshop");
    //get attributes of webshop tag and do something...

    while(reader.ReadToFollowing("item"))
    {
         Console.WriteLine("Item");
        //get attributes of item tag and do something...
    }
}

当 xml 为单行、混合或标签自行关闭时(&lt;item/&gt; 而不是&lt;item&gt;&lt;/item&gt;),我永远不会获得所有数据。大多数时候,读者只是在&lt;webshop&gt;&lt;item&gt; 的一个实例之后停下来

是否有一种强大的方法来解析这个 xml,即使事先不知道确切的衬里?我想遍历所有网店,并为每个网店循环所有商品,然后对这些数据做一些事情。

【问题讨论】:

  • 您在滥用 XmlReader。使用 LINQ to XML;它更易于使用。
  • 究竟是什么被滥用了?您能否提供有关“使用 Linq to XML”的更多详细信息?有教程或参考吗?
  • 我想也许他的意思是你在“使用”XmlReader,这与误用非常相似。请改用 LINQ to XML。
  • XmlReader 将用于大型文档,我认为没有理由在这里使用它。 LinqToXml 是一个简单的 google,XmlDocument 类也可以处理这个问题。你需要把你的 xml 放在头上,多行是文本文档。

标签: c# xml xml-parsing


【解决方案1】:

请查看此堆栈溢出讨论中的答案。

binding xml elements to model in MVC4

基本上,有很多方法可以在您的 c# 代码中读取 xml 文件。这一切都取决于您要实现的目标以及它必须具有的灵活性。我个人更喜欢XmlSeriealizer,因为它将 xml 转换为 c# 对象。唯一的缺点是您必须为要转换的 xml 定义类。

【讨论】:

    【解决方案2】:

    这是一个非常简单的 Linq to XML 读取 xml 文件的方法:

    var xml = @"<webshop><item></item><item></item></webshop>";
    
    var reader = XDocument.Parse(xml);
    
    var webshops = from w in reader.Elements("webshop")
                    select w;
    
    foreach(var shop in webshops)
    {
        var items = from i in shop.Elements("item")
                    select i;
    
        //can now grab any attributes of the items
    }
    

    如果没有关于这些元素中属性的更多详细信息,我无法在示例中提供更多详细信息,但我认为这足以向您展示如何做到这一点。

    如果您不打算进行任何过滤并且只想要所有 webshop 元素,然后是它们的组成 item 子元素,您可以像这样简化我上面的内容:

    var webshops = reader.Elements("webshop");
    
    foreach(var shop in webshops)
    {
        var items = shop.Elements("item");
    
        //can now grab any attributes of the items
    }
    

    我最初包含了更详细的查询结构方式,以防您想要进行任何过滤或想要做一些更复杂的事情,然后简单地选择给定的元素。这种简化的方法将产生与我的第一个示例相同的结果。

    【讨论】:

    • 没有任何理由写from x in y select x
    • @SLaks 我同意,一般来说,但由于 OP 对 Linq to XML 没有明显的了解,我认为出于演示目的我会过于冗长,而且他的示例足够稀疏,我认为我'会保持这种格式,所以如果他确实想做任何过滤或其他处理,添加起来很简单。
    • 否;你只是在教他写无用的代码而不理解它。如果你在这种情况下给出完整的代码,大多数用户会盲目地粘贴你的代码,而没有阅读任何文档或理解它的含义。
    • 首先,我认为没有必要假设我有能力阅读类似 sql 的语句。其次,我对代码示例的欣赏远胜于 cmets,因为这些示例不是最优的。谢谢。
    • 我认为你的 cmets 会更好,如果你不仅能说出问题所在,还能说出问题的原因以及可能的解决方案是什么。当然,我知道(你)我们的时间很昂贵,所以即使是最少量的信息,我也很感激。
    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 2013-06-16
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多