Как получить внутренний текст в XML

У меня есть следующий файл XML

<?xml version="1.0" encoding="utf-8"?>
<Comprobante version="2.2" serie="A" folio="35207" fecha="2013-05-31T11:51:48">
 <Emisor rfc="" nombre="E">
  <DomicilioFiscal calle="" noExterior="" colonia="" />
  <ExpedidoEn calle="" noExterior="" colonia="" />
  <RegimenFiscal Regimen="Regimen" />
 </Emisor>

 <Receptor rfc="" nombre="Z">
  <Domicilio calle="" noExterior="" colonia="" />
 </Receptor>

 <Conceptos cantidad="1.000" unidad="COMISION" descripcion="PENDIENTE" valorUnitario="28.50000" importe="28.50" />

 <Impuestos totalImpuestosTrasladados="3.14">
  <Traslados>
   <Traslado impuesto="IVA" tasa="11.00" importe="3.14" />
  </Traslados>
 </Impuestos>

 <Addenda>
  <ener:EstadoDeCuentaCombustible xmlns:ener="">
   <ener:cadenaOriginal>||2.2|A|35207|2013-05-31T11:51:48|773463|2011|ingreso|Pago en una sola exhibicion|28.50|31.64|Tarjeta|Tijuana,Baja California|3213|ERE|E S.A. de C.V.|Prol|13351|Anexa e|Tijuana|Tijuana|Baja California|Mexico|22100|Prol|13351|Anexa e|Tijuana|Tijuana|Baja California|Mexico|22100|Regimen|XA|Z||||TIJUANA|TIJUANA|BAJA CALIFORNIA|Mexico||1.000|COMISION|PENDIENTE|28.50000|28.50|IVA|11.00|3.14|3.14||</ener:cadenaOriginal>
   <ener:idRefund>98</ener:idRefund>
  </ener:EstadoDeCuentaCombustible>
 </Addenda>
</Comprobante>

Мне нужно получить текст внутри (эта длинная строка)

Вот как я запускаю код С#

XmlDocument doc = new XmlDocument();
doc.Load("Route");

XmlNamespaceManager xnm = new XmlNamespaceManager(doc.NameTable);

xnm.AddNamespace("Documento", "http://www.sat.gob.mx/cfd/2");
xnm.AddNamespace("ener", "http://www.enercard.com.mx/cfd");

Я пробовал разные способы...

//strOriginalString = doc.DocumentElement.SelectSingleNode("//Documento:Addenda", xnm).FirstChild.SelectSingleNode("//ener:cadenaOriginal", xnm).InnerText;
//strOriginalString = doc.DocumentElement.SelectSingleNode("//Documento:Addenda//ener:EstadoDeCuentaCombustible", xnm).FirstChild.SelectSingleNode("//ener:cadenaOriginal", xnm).InnerText;
//strOriginalString = doc.DocumentElement.SelectSingleNode("//Documento:Addenda/Documento:cadenaOriginal", xnm).InnerXml;

эти 3 способа всегда вызывают исключение...

Я нашел другой способ, который не генерирует исключение, но не получает строку

XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("/Addenda/EstadoDeCuentaCombustible");
strOriginalString = "";

foreach (XmlNode node in nodes)
{
    XmlNode child = node.SelectSingleNode("./cadenaOriginal");

    if (child != null)
    {
        strOriginalString = child.InnerText;
        break;
    }
}

Что я делаю не так? или есть другой способ получить строку внутри


person Victor    schedule 05.06.2013    source источник
comment
Я смущен. Ваш XML объявляет префикс пространства имен ener пустым пространством имен, но ваше сопоставление говорит что-то другое. Кроме того, сопоставление имеет пространство имен Documento, но в вашем документе его нет.   -  person svick    schedule 05.06.2013


Ответы (4)


Это несколько упрощено, и вам придется иметь дело с проблемами пространства имен (одну из них я отмечу ниже), но в остальном это основная конструкция:

        XmlDocument doc = new XmlDocument();
        try { doc.Load("c:\\temp\\test.xml"); }
        catch (Exception ex) { }
        XmlElement root = doc.DocumentElement;
        String strOriginalString = "";

        foreach (XmlNode node in root.SelectNodes("/Comprobante/Addenda"))
        {
            XmlNode child = node.SelectSingleNode("EstadoDeCuentaCombustible/cadenaOriginal");
            if (child != null)
            {
                strOriginalString = child.InnerText;
                break;
            }
        }

Возникла проблема с <ener:EstadoDeCuentaCombustible xmlns:ener="">, так как пустое пространство имен недействительно.

person DonBoitnott    schedule 05.06.2013

В вашем XML-документе отсутствует объявление xmlns:ener:

<ener:EstadoDeCuentaCombustible xmlns:ener="http://www.enercard.com.mx/cfd">

Исправьте это, и вы сможете использовать что-то вроде этого:

string xpath = "/Comprobante/Addenda/ener:EstadoDeCuentaCombustible";
foreach (XmlNode estado in doc.SelectNodes(xpath, xnm))
{
    Console.WriteLine("ener:cadenaOriginal={0}", 
        estado.SelectSingleNode("ener:cadenaOriginal", xnm).InnerText);
}
person Rubens Farias    schedule 05.06.2013

Я считаю, что Linq2Xml проще в использовании. (Предполагая, что у вас есть допустимое пространство имен в xmlns:ener="").

var xDoc = XDocument.Load(filename);
XNamespace ener = "your name space for ex ,http://www.enercard.com.mx/cfd";
var result = xDoc.Descendants(ener + "cadenaOriginal").First().Value;
person I4V    schedule 05.06.2013

Ваша вторая попытка выглядит наиболее близкой к тому, что должно работать:

//strOriginalString = doc.DocumentElement.SelectSingleNode("//Documento:Addenda//ener:EstadoDeCuentaCombustible", xnm).FirstChild.SelectSingleNode("//ener:cadenaOriginal", xnm).InnerText;

Но переключитесь на это (отредактировано):

//strOriginalString = doc.SelectSingleNode("//ener:cadenaOriginal", xnm).InnerText;
person panhandel    schedule 05.06.2013
comment
выдает следующее исключение Namespace Manager или XsltContext. Этот запрос имеет префикс, переменную или определяемую пользователем функцию. - person Victor; 05.06.2013
comment
Я должен был оставить ваш , xnm внутри вызова SelectSingleNode; редактирование ответа - person panhandel; 05.06.2013
comment
Я также должен отметить, что мне пришлось отредактировать файл xml, чтобы включить объявление xmlns:ener, как и другие, которые также упоминали о необходимости. - person panhandel; 05.06.2013