读取 XML 文件中的下一个值

Read next value in XML file

我有一个这样的 XML 文件:

    <key>businessAddress</key>
    <string>Moka</string>
    <key>businessName</key>
    <string>Moka address</string>
    <key>Id</key>
    <string>39</string>
    <key>Cat</key>
    <string>216</string>
    <key>deals</key>

如果键是 Id

,我想读取下一个 <string>

所以我所做的是:

XmlTextReader reader = new XmlTextReader(file);

while (reader.Read())
{
    if (reader.Value.Equals("Id"))
    {
        reader.MoveToNextAttribute
    }  
}

但是我没有成功。

感谢帮助

您可以使用布尔标志来指示您是否应该读取下一个元素的值:

bool shouldReadId = false;
while (reader.Read())
{
    if (reader.NodeType == XmlNodeType.Text && shouldReadId)
    {
        Console.WriteLine(reader.Value); // will print 39
        shouldReadId = false;
    }

    if (reader.Value.Equals("Id"))
    {
        // indicate that we should read the value of the next element
        // in the next iteration
        shouldReadId = true;
    }
}

我想指出 XmlTextReader is basically replaced with XmlReader:

Starting with the .NET Framework 2.0, we recommend that you use the System.Xml.XmlReader class instead.

尽管他们的对象模型没有任何显着差异。

所以,如果你想使用 XmlTextReader,你可以这样做:

public static class XmlReaderExtensions
{
    public static void EnsureRead(this XmlTextReader reader)
    {
        var isRead = reader.Read();
        if (!isRead)
            throw new InvalidOperationException("Failed to read");
    }

    public static void SkipUntil(this XmlTextReader reader, Func<XmlTextReader, Boolean> isStop)
    {
        while (!isStop(reader))
        {
            reader.EnsureRead();
        }
    }
}

...

var xml = @"<root>   <key>businessAddress</key>
    <string>Moka</string>
    <key>businessName</key>
    <string>Moka address</string>
    <key>Id</key>
    <string>39</string>
    <key>Cat</key>
    <string>216</string>
    <key>deals</key> </root>";

using (var stream = new MemoryStream(Encoding.Default.GetBytes(xml)))
using (var reader = new XmlTextReader(stream))
{
    reader.SkipUntil(cur => cur.Value == "Id");
    reader.EnsureRead(); // Skip current node
    reader.SkipUntil(cur => cur.NodeType == XmlNodeType.Text);
    Console.WriteLine("The id from XmlTextReader is {0}", reader.Value);
}

虽然要确保它 正常工作 快速失败一些 xml,但与给定的模式不对应,您将必须添加一个更多的完整性检查,所以...


如果您不关心将整个 xml 树放入内存,您也可以尝试 LINQ-TO-XML

using (var stream = new MemoryStream(Encoding.Default.GetBytes(xml)))
{
    var xdoc = XDocument.Load(stream);
    var id = xdoc
        .Root
        .Elements("key")
        .First(element =>
            element.Value == "Id")
        .ElementsAfterSelf("string")
        .First()
        .Value;
    Console.WriteLine("The id from XDocument is {0}", id);
}

您的 XML 看起来与 Plist. So, sounds like you need a Plist library. Instead of reinventing the wheel, just use any of the libraries available on NuGet 非常相似。他们将通过解析 XML 文件来解决您的问题。

如果您坚持手动解析 XML,请忘记低级 SAX class,只需使用 DOM。使用 XDocument 更容易。请参阅 @EugenePodskal 的解决方案。