Невозможно получить значения всех элементов в XML с использованием XmlNodeList и XmlNamespaceManager - PullRequest
0 голосов
/ 09 октября 2019

Я разбираю ниже XML. Мне нужно значение «x2@email.com». Я могу успешно получить список узлов, но проблема в том, что на каждой итерации я все еще получаю «x1@email.com» из первой группы элемента «Info».

XML:

<ClaimAdminContact xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Services.Models">
  <claimAdminID>T1</claimAdminID>
  <contactInfo>
    <Info>
      <desc>Level 1 Notifications</desc>
      <emailAddress>x1@email.com</emailAddress>
      <orgNum>1234</orgNum>
      <type>T2</type>
    </Info>
    <Info>
      <desc>Level 2 Notifications</desc>
      <emailAddress>x2@email.com</emailAddress>
      <orgNum i:nil="true"/>
      <type>T2</type>
    </Info>
    <Info>
      <desc>Level 3 Notifications</desc>
      <emailAddress>x3@email.com</emailAddress>
      <orgNum i:nil="true"/>
      <type>T2</type>
    </Info>
  </contactInfo>
</ClaimAdminContact>

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

Код:

      XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlEmail.NameTable);
            nsmgr.AddNamespace("MsBuild", xmlns);
            var contactInfo = xmlEmail.SelectNodes("/MsBuild:ClaimAdminContact/MsBuild:contactInfo/*", nsmgr);

            foreach (XmlNode item in contactInfo)
            {
                _notificationDesc = item.SelectSingleNode("//MsBuild:desc", nsmgr).InnerText;
                _reviewEmail = item.SelectSingleNode("//MsBuild:emailAddress", nsmgr).InnerText;
                _orgNum = item.SelectSingleNode("//MsBuild:orgNum", nsmgr).InnerText;
            }

Пожалуйста,

Ответы [ 3 ]

1 голос
/ 10 октября 2019

Использовать xml linq:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            XNamespace ns = doc.Root.GetDefaultNamespace();

            var results = doc.Descendants(ns + "Info").Select(x => new
            {
                desc = (string)x.Element(ns + "desc"),
                email = (string)x.Element(ns + "emailAddress"),
                orgNum = (string)x.Element(ns + "orgNum"),
                type = (string)x.Element(ns + "type")
            }).ToList();
        }
    }
}
1 голос
/ 10 октября 2019

Использование System.Xml.Linq:

var xmlFile = @"myxml.xml";
var xDoc = XDocument.Load(xmlFile);
var infos = xDoc.Descendants("Info");
foreach (var info in infos)
{
    var email = info.Element("emailAddress").Value;
}

РЕДАКТИРОВАТЬ: Как работать с пространствами имен

Если у вас есть несколько пространств имен и вы хотите работать с этим, то вы должны указатьпространства имен, как показано ниже. Удаление пространств имен из файла вряд ли является хорошей идеей.

var xmlFile = @"C:\Users\gurudeniyas\Desktop\myxml.xml";
XNamespace ns = "http://schemas.datacontract.org/2004/07/Services.Models";
XNamespace nsi = "http://www.w3.org/2001/XMLSchema-instance";
var xDoc = XDocument.Load(xmlFile);
var infos = xDoc.Descendants(ns + "Info");
foreach (var info in infos)
{
    var email = info.Descendants(ns + "emailAddress").FirstOrDefault().Value;
    Console.WriteLine(email);
}
0 голосов
/ 10 октября 2019

Основной проблемой, с которой я столкнулся при разборе xml, был атрибут namespace в корневом элементе. Это мешало моему коду анализировать обычным способом, и именно поэтому я попытался использовать «XmlNamespaceManager». Я решил удалить пространство имен из XML.

Я использовал ниже рекурсивный метод для удаления пространства имен из XML, и все заработало !! Я не уверен, что это оптимальный путь, но я смог добиться того, чего хотел.

public XElement RemoveAllNamespaces(XElement root)
        {
            return new XElement(
                root.Name.LocalName,
                root.HasElements ?
                    root.Elements().Select(x => RemoveAllNamespaces(x)) :
                    (object)root.Value

                );
        }

Телефонный код:

XElement noNsDoc = RemoveAllNamespaces(XElement.Parse(xmlString));

var xDoc = XDocument.Parse(noNsDoc.ToString());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...