在 C# 中使用 XPathNavigator 添加和操作多个子节点

发布于 2024-09-27 17:30:37 字数 1643 浏览 2 评论 0原文

我正在编写与 XML 进行序列化(反序列化)的类。序列化和反序列化时,该类获取一个 XPathNavigator 来从中获取数据/向其中添加数据。

因为该类可能包含也需要序列化的对象(使用相同的机制),所以我执行以下操作来为每个对象添加一个子元素:

public void Serialize(XPathNavigator navigator)
{

    foreach(IXmlSerializableObject o in objects) {

        // Create child element.
        navigator.AppendChildElement(string.Empty, "child", string.Empty, null);

        // Move to last child element.
        navigator.MoveToChild(XPathNodeType.Element);
        while (navigator.MoveToNext(XPathNodeType.Element)) ;

        // Serialize the object at the current node.
        // This will add attributes and child elements as required.
        // The navigator will be positiononed at the same node after the call.
        o.Serialize(navigator);

        navigator.MoveToParent();
    }

}

特别是 MoveToParent/Move to last child 部分似乎是非常错误的(尽管它作品)。有更好的方法吗?

我使用的另一种方法(以避免对象访问迄今为止存储的信息)是:

foreach(IXmlSerializableObject o in objects) {
{

    // Create a new (empty) document for object serialization.
    XPathNavigator instructionNavigator = new XmlDocument().CreateNavigator();
    instructionNavigator.AppendChildElement(string.Empty, "child", string.Empty, null);
    instructionNavigator.MoveToChild(XPathNodeType.Element);

    // Serialize the object.
    o.Serialize(instructionNavigator);

    // Now add the serialized content to the navigator.
    instructionNavigator.MoveToRoot();
    instructionNavigator.MoveToChild(XPathNodeType.Element);
    navigator.AppendChild(instructionNavigator);
}

这两种方法似乎都是间接的,因为它们都会产生大量开销。我会感谢任何关于如何改进我的算法的想法或提示。

问候, 多米尼克

I'm writing classes which (de)serialize to/from XML. When serializing and deserializing, the class gets a XPathNavigator to get data from/add data to.

Because the class may contain objects which are need to be serialized too (using the same mechanism), I do the following to add a child element for each object:

public void Serialize(XPathNavigator navigator)
{

    foreach(IXmlSerializableObject o in objects) {

        // Create child element.
        navigator.AppendChildElement(string.Empty, "child", string.Empty, null);

        // Move to last child element.
        navigator.MoveToChild(XPathNodeType.Element);
        while (navigator.MoveToNext(XPathNodeType.Element)) ;

        // Serialize the object at the current node.
        // This will add attributes and child elements as required.
        // The navigator will be positiononed at the same node after the call.
        o.Serialize(navigator);

        navigator.MoveToParent();
    }

}

Especially the MoveToParent/Move to last child part seems to be awfully wrong (though it works). Is there a better way to do this?

Another approach I use (to avoid that objects get access to information stored so far) is this:

foreach(IXmlSerializableObject o in objects) {
{

    // Create a new (empty) document for object serialization.
    XPathNavigator instructionNavigator = new XmlDocument().CreateNavigator();
    instructionNavigator.AppendChildElement(string.Empty, "child", string.Empty, null);
    instructionNavigator.MoveToChild(XPathNodeType.Element);

    // Serialize the object.
    o.Serialize(instructionNavigator);

    // Now add the serialized content to the navigator.
    instructionNavigator.MoveToRoot();
    instructionNavigator.MoveToChild(XPathNodeType.Element);
    navigator.AppendChild(instructionNavigator);
}

Both approaches seem to be somehow circumstantial as they both create lots of overhead. I would appriciate any ideas or hints on how to improve my algorithm.

greetings,
Dominik

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

野却迷人 2024-10-04 17:30:37

正如 Jon Skeet 在他的评论中建议的那样,我现在使用 XmlReader 和 XmlWriter 而不是 XPathNavigator。这看起来更干净;

public void Serialize(XmlWriter writer)
{

    foreach (Instruction task in this.Tasks)
    {
        writer.WriteStartElement(task.Tag);

        task.Serialize(writer);

        writer.WriteEndElement();
    }
}

谢谢!

As Jon Skeet suggested in his comment, I now use XmlReader and XmlWriter instead of XPathNavigator. This seems much cleaner;

public void Serialize(XmlWriter writer)
{

    foreach (Instruction task in this.Tasks)
    {
        writer.WriteStartElement(task.Tag);

        task.Serialize(writer);

        writer.WriteEndElement();
    }
}

Thanks!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文