XmlReader для возврата узла как есть без детей - PullRequest
0 голосов
/ 15 сентября 2011

Я перебираю большой XML-документ, используя XmlReader, и объединяю его в гораздо меньший и более управляемый XmlDocmuent.По пути я нахожу интересный узел, поэтому для его перемещения я делаю так:

        targetDoc.LoadXml("<result></result>");
        // Some interesting code removed
        using (XmlReader r = XmlReader.Create(file))
        {
            while (r.Read())
            {
                if (r.NodeType == XmlNodeType.Element)
                {
                    if (r.Name == match)
                    {
                        // Put the node into the target document
                        targetDoc.FirstChild.InnerXml = r.ReadOuterXml();
                        return targetDoc;
                    }
                }
             }
         }

Это все хорошо, за исключением того, что я хотел бы включить узел без его потомков .Что меня интересует, так это сам узел с его атрибутами.Потомки очень большие, громоздкие и неинтересные на данный момент.(И одновременное чтение их в память вызовет ошибки нехватки памяти ...)

Есть ли простой способ получить текст (?) Найденного элемента с его атрибутами - но не его потомки- в целевой документ?

Ответы [ 3 ]

1 голос
/ 15 сентября 2011

Я не думаю, что есть встроенный способ сделать это. Я думаю, что вы должны прочитать атрибуты и содержание самостоятельно.

, например

static void Main(string[] args)
        {
            var xml = @"<root>
                                <parent a1 = 'foo' a2 = 'bar'>Some Parent text
                                    <child a3 = 'frob' a2= 'brob'> Some Child Text
                                    </child>
                                </parent>
            </root>";
            var file = new StringReader(xml) ;

            using (XmlReader r = XmlReader.Create(file))
            {
                while (r.Read())
                {
                    if (r.NodeType == XmlNodeType.Element)
                    {
                        if (r.Name == "parent")
                        {
                            var output = new StringBuilder();
                            var settings = new XmlWriterSettings();
                            settings.OmitXmlDeclaration = true;
                            using (var elementWriter = XmlWriter.Create(output, settings))
                            {   

                                elementWriter.WriteStartElement(r.Name);

                                elementWriter.WriteAttributes(r,false);
                                elementWriter.WriteValue(r.ReadString());
                                elementWriter.WriteEndElement();
                            }

                            Console.WriteLine(output.ToString());
                        }
                    }
                }
            }


            if (System.Diagnostics.Debugger.IsAttached)
                Console.ReadLine();

        }

Будет производить

<parent a1="foo" a2="bar">Some Parent text</parent>
Press any key to continue . . .
0 голосов
/ 15 сентября 2011

Не обязательно отличный способ, но вы можете читать строку, пока не доберетесь до конца начального тега, а затем вручную добавить конечный тег и загрузить его в XmlDocument.

edit:

Думая что-то вроде:

string xml = r.ReadOuterXml();
int firstEndTag = xml.IndexOf('>');
int lastStartTag = xml.LastIndexOf('<');
string newXml = xml.Substring(0, firstEndTag) + xml.Substring(lastStartTag);

Это может быть недопустимо, учитывая, что здесь есть большая строка.Ваш путь может быть лучшим.И то и другое не красиво, но я лично не могу придумать лучшего пути, учитывая ваши ограничения (что не означает, что лучшего способа не существует).

0 голосов
/ 15 сентября 2011

Вы можете попробовать метод XmlNode.CloneNode (bool deep).

deep: true для рекурсивного клонирования поддерева под указанным узлом;false для клонирования только самого узла.

...