2009-01-19 7 views
5

J'ai un fichier xml à partir de laquelle j'extrais html en utilisant LINQ to XML. Voici un exemple du fichier:Gardez les balises HTML en XML en utilisant LINQ to XML

<?xml version="1.0" encoding="utf-8" ?> 
<tips> 
    <tip id="0"> 
    This is the first tip. 
</tip> 
<tip id="1"> 
    Use <b>Windows Live Writer</b> or <b>Microsoft Word 2007</b> to create and publish content. 
</tip> 
<tip id="2"> 
    Enter a <b>url</b> into the box to automatically screenshot and index useful webpages. 
</tip> 
<tip id="3"> 
    Invite your <b>colleagues</b> to the site by entering their email addresses. You can then share the content with them! 
</tip> 
</tips> 

J'utilise la requête suivante pour extraire une « pointe » du fichier:

Tip tip = (from t in tipsXml.Descendants("tip") 
        where t.Attribute("id").Value == nextTipId.ToString() 
        select new Tip() 
        { 
        TipText= t.Value, 
        TipId = nextTipId 
        }).First(); 

Le problème que j'ai est que les éléments de Html sont dépouillés en dehors. J'espérais utiliser quelque chose comme InnerHtml au lieu de Value, mais cela ne semble pas être là.

Des idées?

Merci à tous à l'avance,

Dave

Répondre

8

Appel t.ToString() au lieu de Value. Cela renverra le XML en tant que chaîne. Vous pouvez utiliser la surcharge prenant SaveOptions pour désactiver la mise en forme. Je ne peux pas vérifier maintenant, mais je soupçonne qu'il inclura l'étiquette d'élément (et les éléments) de sorte que vous devriez enlever ceci.

Notez que si votre HTML est pas XML valide, vous retrouvez avec un fichier XML global non valide.

Le format du fichier XML complètement hors de votre contrôle? Il serait plus agréable pour n'importe quel HTML à l'intérieur d'être codé en XML.

EDIT: Une façon d'éviter d'obtenir la partie extérieure pourrait être de faire quelque chose comme ceci (dans une méthode distincte appelée à partir de votre requête, bien sûr):

StringBuilder builder = new StringBuilder(); 
foreach (XNode node in element.Nodes()) 
{ 
    builder.Append(node.ToString()); 
} 

De cette façon, vous obtiendrez des éléments HTML avec leurs descendants et les nœuds de texte entremêlés. Fondamentalement, c'est l'équivalent de InnerXml, je soupçonne fortement.

+1

heh, enclencher le montage. Encoder HTML à l'intérieur de XML est commun et pratique pour ce genre de cas; l'alternative serait d'utiliser XHTML valide, en déclarant les xmlns XHTML par défaut et en plaçant les éléments tip/tips dans un espace de noms différent pour éviter de confondre les deux. – bobince

0

TipText = t.Value,

XElement.value renvoie uniquement le texte qui est directement à l'intérieur de l'élément. Texte dans des éléments imbriqués - HTML ou autrement - ne sera pas inclus, et bien sûr des références -entity-& apparaîtra sous leur forme décodé.

Si vous voulez que le contenu en tant que chaîne avec des balises que vous pouvez appeler XElement.ToString(), éventuellement avec SaveOptions.DisableFormatting. Mais notez que ceci inclut l'élément tip < d'emballage - c'est-à-dire, dans les termes DOM du navigateur web, c'est le outerHTML et non le innerHTML. Pour obtenir l'innerHTML, vous devez réunir tous les ToString() de l'enfant XElement.Nodes.

1

Il suffit d'utiliser string.Concat(tip.Nodes()) pour obtenir le contenu avec les balises HTML