c# xmldocument получить все узлы братьев и сестер после определенного

Допустим, у меня есть следующий xml:

<Report>
    <Tablix></Tablix>
    <Textbox Name="TextboxSearchInjection"></Textbox>
    <Textbox></Textbox>
    <Tablix></Tablix>
    <Textbox></Textbox>
    <Textbox Name="TextboxSearchInjectionEnd">
       <Height>1</Height>
    </Textbox>
    <Tablix>
       <Height>1</Height>
    </Tablix>
   <Textbox>
       <Height>2</Height>
    </Textbox>
   <Textbox></Textbox>
   <Tablix>
      <Height>1</Height>
   </Tablix>
   <Textbox>
       <Height>3</Height>
    </Textbox>
</Report>

Как получить все узлы братьев и сестер после <Textbox Name="TextboxSearchInjectionEnd"> и обновить значение в высоте, используя XmlDocument в С#? Итак, наконец, я получу список узлов, таких как Textbox и Tablix, но начиная с узла <Textbox Name="TextboxSearchInjectionEnd">. Я не хочу раньше.


person zawier    schedule 15.02.2021    source источник
comment
Зачем использовать старый XmlDocument, а не более современный и удобный XDocument?   -  person dbc    schedule 16.02.2021
comment
Извините, я забыл удалить некоторые теги, теперь это должен быть правильный xml. Зачем использовать XmlDocument - хороший вопрос, потому что все мое решение, к сожалению, основано на старой технологии, и для сохранения согласованности я хотел бы решить эту проблему.   -  person zawier    schedule 16.02.2021
comment
Вы хотите изменить высоту родственных узлов <Textbox Name="TextboxSearchInjectionEnd"> или вы также хотите обновить высоту самого <Textbox Name="TextboxSearchInjectionEnd">?   -  person dbc    schedule 16.02.2021
comment
Оба +высота Табликса, а также   -  person zawier    schedule 16.02.2021


Ответы (2)


Вы можете получить все последующие одноуровневые узлы, используя NextSibling. Например,

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
var node = doc.SelectSingleNode(@"//*[@Name='TextboxSearchInjectionEnd']");
var result = GetAllSucceedingSiblingNodes(node);

Где GetAllSucceedingSiblingNodes определяется как

IEnumerable<XmlNode> GetAllSucceedingSiblingNodes (XmlNode node)
{
    var currentNode = node.NextSibling; // Use currentNode = node if you want to include searched node
    while(currentNode!=null)
    {
        yield return currentNode;
        currentNode = currentNode.NextSibling;
    }
}
person Anu Viswan    schedule 15.02.2021
comment
Спасибо Ану за решение! Работает почти отлично. Есть небольшая проблема. Я обновил свой предыдущий пример xml и добавил к одному атрибуту узла Name=TextboxSearchInjection. В этом случае сценарий занимает все мои узлы. Как это исправить? И да, мне действительно нужно использовать var currentNode = node; - person zawier; 16.02.2021
comment
Что касается упомянутого вами сбоя, не могли бы вы проверить его, используя следующий dotnetfiddle.net/w30UMS. - person Anu Viswan; 16.02.2021

Хорошо, Ану, у меня есть решение, основанное на вашем:

        private static IEnumerable<XmlNode> GetAllSucceedingSiblingNodes(XmlNode node, XmlNamespaceManager nsmgr)
        {
            var currentNode = node;//.NextSibling; // Use currentNode = node if you want to include searched node
            while (currentNode != null &&
                currentNode.Attributes["Name"].Value != "TextboxSearchInjection")
            {
                yield return currentNode;
                currentNode = currentNode.NextSibling;
            }
        }

Еще раз большое спасибо!

person zawier    schedule 16.02.2021
comment
Я не думаю, что вам нужен этот 'currentNode.Attributes[Name].Value != TextboxSearchInjection)' здесь. Не могли бы вы проверить следующее dotnetfiddle.net/w30UMS. - person Anu Viswan; 16.02.2021
comment
К сожалению, мне это нужно, иначе требуется TextboxSearchInjection, а также братья и сестры TextboxSearchInjectionEnd. - person zawier; 16.02.2021