kzen.dev
  • Întrebări
  • Tag-uri
  • Utilizatori
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
Mike Powell
Mike Powell
Question

Cel mai bun mod de a obține InnerXml de o XElement?

Ce's cel mai bun mod de a obține conținutul amestecat "corp" element în codul de mai jos? Elementul poate conține fie XHTML sau text, dar vreau doar conținutul său în șir formă. Anii XmlElement tip a InnerXml de proprietate, care este exact ceea ce am'm după.

Codul scris aproape face ce vreau, dar include jur <body>...` element, care nu't vrei.

XDocument doc = XDocument.Load(new StreamReader(s));
var templates = from t in doc.Descendants("template")
                where t.Attribute("name").Value == templateName
                select new
                {
                   Subject = t.Element("subject").Value,
                   Body = t.Element("body").ToString()
                };
144 2008-08-06T18:16:55+00:00 15
Amirhossein Mehrvarzi
Amirhossein Mehrvarzi
Întrebarea editată 30 mai 2015 в 8:04
Programare
.net
xml
xelement
innerxml
Solution / Answer
Luke Sampson
Luke Sampson
9 noiembrie 2009 в 11:08
2009-11-09T23:08:14+00:00
Mai mult
Sursă
Editează
#8409170

Am vrut să văd care dintre aceste soluții sugerate comportat cel mai bine, așa că am făcut niște teste comparative. De curiozitate, am comparat, de asemenea, LINQ metode de câmpie vechi System.Xml metoda propusă de Greg. Variația a fost interesant și nu ceea ce am așteptat, cu cel mai lent metode fiind mai mult de 3 ori mai lent decât cel mai rapid.

Rezultatele comandat prin cel mai rapid la cel mai lent:

  1. CreateReader - Exemplu Hunter (0.113 secunde)
  2. Simplu vechi System.Xml - Greg Hurlman (0.134 secunde)
  3. Agregat cu concatenarea string - Mike Powell (0.324 secunde)
  4. StringBuilder - Vin (0.333 secunde)
  5. Șir.Alăturați-vă pe array - Terry (0.360 secunde)
  6. Șir.Concat pe array - Marcin Kosieradzki (0.364)

****Metode de

Am folosit un singur document XML cu 20 de noduri identice (numit 'indicii'):

<hint>
  <strong>Thinking of using a fake address?</strong>
  <br />
  Please don't. If we can't verify your address we might just
  have to reject your application.
</hint>

Numerele afișate după câteva secunde de mai sus sunt rezultatul de extragere a "interior XML" de la 20 de noduri, de 1000 de ori într-un rând, și de a lua mediu (medie) de 5 puncte. Am't includ timpul necesar pentru a încărca și parse XML într-un XmlDocument (pentru System.Xml metoda) sau XDocument (pentru toate celelalte).

LINQ algoritmi-am folosit au fost: (C# - să ia toate o XElement "părinte" și a reveni la interior XML string)

CreateReader:

var reader = parent.CreateReader();
reader.MoveToContent();

return reader.ReadInnerXml();

Agregat cu concatenarea string:

return parent.Nodes().Aggregate("", (b, node) => b += node.ToString());

StringBuilder:

StringBuilder sb = new StringBuilder();

foreach(var node in parent.Nodes()) {
    sb.Append(node.ToString());
}

return sb.ToString();

String.Alăturați-vă pe matrice:

return String.Join("", parent.Nodes().Select(x => x.ToString()).ToArray());

String.Concat pe matrice:

return String.Concat(parent.Nodes().Select(x => x.ToString()).ToArray());

Nu am't demonstrat "Simplu vechiul Sistem.Xml" algoritmul de aici ca's a sunat .InnerXml pe noduri.


Concluzie

Dacă performanța este importantă (de exemplu, o mulțime de XML, analizat în mod frecvent), am'd utilizarea Daniel's CreateReader metoda de fiecare dată. Daca're face doar câteva întrebări, s-ar putea doriți să utilizați Mike's mai concis Agregate metodă.

Daca're folosind XML pe elemente mari, cu o mulțime de noduri (poate 100's) ai'd începe, probabil, să vadă beneficiu de a folosi StringBuilder peste Agregate metoda, dar nu s-a terminatCreateReader. Eu nu&#39;t cred căse Alăture " și " Concat` metode ar fi mai eficientă în aceste condiții, pentru că de pedeapsa de a converti o listă mare pentru o gamă largă (chiar evident cu mici liste).

Markus Safar
Markus Safar
Răspuns editat 7 februarie 2016 в 5:40
204
0
Instance Hunter
Instance Hunter
18 martie 2009 в 5:17
2009-03-18T17:17:25+00:00
Mai mult
Sursă
Editează
#8409166

Cred că aceasta este o metoda mult mai buna (in VB, ar trebui't fi greu de tradus):

Având o XElement x:

Dim xReader = x.CreateReader
xReader.MoveToContent
xReader.ReadInnerXml
69
0
 Vin
Vin
19 august 2008 в 8:29
2008-08-19T20:29:41+00:00
Mai mult
Sursă
Editează
#8409164

Cum despre utilizarea acestui "extensia" metoda pe XElement? a lucrat pentru mine !

public static string InnerXml(this XElement element)
{
    StringBuilder innerXml = new StringBuilder();

    foreach (XNode node in element.Nodes())
    {
        // append node's xml string to innerXml
        innerXml.Append(node.ToString());
    }

    return innerXml.ToString();
}

SAU de a folosi un pic de Linq

public static string InnerXml(this XElement element)
{
    StringBuilder innerXml = new StringBuilder();
    doc.Nodes().ToList().ForEach( node => innerXml.Append(node.ToString()));

    return innerXml.ToString();
}

Notă: codul De mai sus pentru a utiliza element.Nodurile () "în opoziție cu" element.Elemente(). Lucru foarte important de reținut diferența între cele două.element.Nodurile()dă totul caXText,XAttributeetc, darXElement` doar un Element.

Markus Safar
Markus Safar
Răspuns editat 7 februarie 2016 в 5:40
18
0
Todd Menier
Todd Menier
4 ianuarie 2013 в 8:21
2013-01-04T20:21:41+00:00
Mai mult
Sursă
Editează
#8409173

Cu toate datorate de credit pentru cei care au descoperit și s-a dovedit cea mai bună abordare (multumesc!), aici este înfășurat într-o metodă de prelungire:

public static string InnerXml(this XNode node) {
    using (var reader = node.CreateReader()) {
        reader.MoveToContent();
        return reader.ReadInnerXml();
    }
}
14
0
Marcin Kosieradzki
Marcin Kosieradzki
31 octombrie 2009 в 5:22
2009-10-31T17:22:59+00:00
Mai mult
Sursă
Editează
#8409169

Păstrați-l simplu și eficient:

String.Concat(node.Nodes().Select(x => x.ToString()).ToArray())
  • Agregat este de memorie și de performanță ineficiente atunci când concatenarea de șiruri
  • Folosind Join("", sth) este folosind două ori mai mare șir de matrice decât Concat... Si arata destul de ciudat în cod.
  • Folosind += se pare foarte ciudat, dar se pare că nu este cu mult mai rău decât folosind '+' - probabil ar fi optimizat pentru același cod, pentru atribuirea rezultatul este neutilizate și ar putea fi eliminat în condiții de siguranță de către compilator.
  • StringBuilder este deci imperativ să - și toată lumea știe că inutile "de stat" e de rahat.
10
0
Mike Powell
Mike Powell
6 august 2008 в 7:36
2008-08-06T19:36:02+00:00
Mai mult
Sursă
Editează
#8409163

Am încheiat cu asta:

Body = t.Element("body").Nodes().Aggregate("", (b, node) => b += node.ToString());
Jeff Atwood
Jeff Atwood
Răspuns editat 7 august 2008 в 10:10
7
0
Martin R-L
Martin R-L
17 martie 2010 в 8:47
2010-03-17T08:47:45+00:00
Mai mult
Sursă
Editează
#8409171

Personal, am ajuns să scriu o InnerXml extinderea metoda se utilizează Agregate metoda:

public static string InnerXml(this XElement thiz)
{
   return thiz.Nodes().Aggregate( string.Empty, ( element, node ) => element += node.ToString() );
}

Codul meu client este apoi doar concis ca ar fi cu cel vechi System.Xml nume:

var innerXml = myXElement.InnerXml();
3
0
Mike Powell
Mike Powell
6 august 2008 в 6:25
2008-08-06T18:25:08+00:00
Mai mult
Sursă
Editează
#8409162

@Greg: Se pare că'am editat raspunsul tau pentru a fi un răspuns complet diferit. La care raspunsul meu este da, am putea face acest lucru, folosind System.Xml dar a fost în speranța de a obține picioarele ude cu LINQ to XML.

Am'll las meu original de răspuns de mai jos în cazul în care altcineva se întreabă de ce nu pot't de a folosi doar XElement's .Valoarea de proprietate pentru a obține ceea ce am nevoie:

@Greg: Valoarea proprietății concateneaza toate conținutul de text de orice noduri copil. Deci, dacă organismul element conține doar text funcționează, dar dacă acesta conține XHTML am obține toate text concatenate împreună, dar nici unul dintre tag-uri.

Mike Powell
Mike Powell
Răspuns editat 7 august 2008 в 2:18
2
0
 user950851
user950851
8 februarie 2014 в 4:55
2014-02-08T04:55:35+00:00
Mai mult
Sursă
Editează
#8409174

// utilizarea Regex ar putea fi mai rapid să tăiați pur și simplu begin și end tag element

var content = element.ToString();
var matchBegin = Regex.Match(content, @"<.+?>");
content = content.Substring(matchBegin.Index + matchBegin.Length);          
var matchEnd = Regex.Match(content, @"</.+?>", RegexOptions.RightToLeft);
content = content.Substring(0, matchEnd.Index);
1
0
 user1920925
user1920925
13 octombrie 2014 в 8:08
2014-10-13T20:08:32+00:00
Mai mult
Sursă
Editează
#8409176

doc.ToString() sau doc.ToString(SaveOptions) functioneaza. Vezi http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.tostring(v=vs. 110).aspx

1
0
Vinod Srivastav
Vinod Srivastav
25 octombrie 2018 в 7:07
2018-10-25T19:07:28+00:00
Mai mult
Sursă
Editează
#8409177
var innerXmlAsText= XElement.Parse(xmlContent)
                    .Descendants()
                    .Where(n => n.Name.LocalName == "template")
                    .Elements()
                    .Single()
                    .ToString();

Va face treaba pentru tine

0
0
Utilizator anonim
18 martie 2009 в 4:57
2009-03-18T16:57:12+00:00
Mai mult
Sursă
Editează
#8409165

Vă întrebați dacă (observați că am scăpat de b+= și au doar b+)

t.Element( "body" ).Nodes()
 .Aggregate( "", ( b, node ) => b + node.ToString() );

ar putea fi mai puțin eficiente decât

string.Join( "", t.Element.Nodes()
                  .Select( n => n.ToString() ).ToArray() );

Nu sunt 100% sigur...dar uitându-se la Agregate() și string.Join() în Reflector...I cred că a citit-o ca Agregat doar adăugarea unui revenind valoare, astfel încât, în esență, veți obține:

string = string + string

față de șir de caractere.Alăturați-vă, acesta are unele mai vorbim acolo de FastStringAllocation sau ceva, care mă face ceva cei de la Microsoft ar putea fi pus un extra boost de performanta acolo. Desigur mele .ToArray() apelul meu nega asta, dar am vrut doar sa ofer o altă sugestie.

0
0
 Ayyash
Ayyash
25 octombrie 2009 в 11:39
2009-10-25T23:39:21+00:00
Mai mult
Sursă
Editează
#8409168

știi? cel mai bun lucru de făcut este de a reveni la CDATA :( im se uită la soluții aici, dar cred că CDATA este de departe cel mai simplu și mai ieftin, nu cel mai convenabil de a dezvolta cu tho

0
0
Greg Hurlman
Greg Hurlman
6 august 2008 в 6:20
2008-08-06T18:20:18+00:00
Mai mult
Sursă
Editează
#8409161

Este posibil să se utilizeze System.Xml nume de obiecte pentru a obține locuri de muncă făcut aici în loc de a folosi LINQ? Ca te-a menționat deja, XmlNode.InnerXml este exact ceea ce ai nevoie.

Greg Hurlman
Greg Hurlman
Răspuns editat 6 august 2008 в 6:36
0
0
 Shivraj
Shivraj
13 august 2010 в 7:05
2010-08-13T07:05:02+00:00
Mai mult
Sursă
Editează
#8409172
public static string InnerXml(this XElement xElement)
{
    //remove start tag
    string innerXml = xElement.ToString().Trim().Replace(string.Format("<{0}>", xElement.Name), "");
    ////remove end tag
    innerXml = innerXml.Trim().Replace(string.Format("</{0}>", xElement.Name), "");
    return innerXml.Trim();
}
-2
0
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
Utilizatori
Toate
Nou
Populare
1
工藤 芳則
Înregistrat 6 zile în urmă
2
Ирина Беляева
Înregistrat 1 săptămână în urmă
3
Darya Arsenyeva
Înregistrat 1 săptămână în urmă
4
anyta nuam-nuam (LapuSiK)
Înregistrat 1 săptămână în urmă
5
Shuhratjon Imomkulov
Înregistrat 1 săptămână în urmă
ID
JA
KO
RO
RU
© kzen.dev 2023
Sursă
stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire