2010-02-16 23 views
0

J'essaie de trouver un moyen d'analyser une balise xml où le contenu est transmis avec des balises CDATA pour certaines entrées, mais pas pour toutes. Par exemple, voici un exemple de contenu que je recevrais pour des données contenant des étiquettes CDATA. Mais il existe d'autres scénarios où les tags CDATA sont ignorés.Implémentation de IXmlSerializable pour le contenu contenant des données avec ou sans balises CDATA

<Data><![CDATA[ <h1>CHAPTER 2<br/> EDUCATION</h1> 
       <P> Analysis paragraph </P> ]]></Data> 

Y at-il une façon élégante de détecter une certaine façon que, et mettre en œuvre la méthode ReadXml qui peut analyser les deux types d'entrée (avec ou sans CDATA)? Jusqu'à présent, mon implémentation de ReadXml() est la suivante, mais j'obtiens des erreurs d'analyse lorsque la balise CDATA est omise.

public void ReadXml(XmlReader reader) 
    { 
     bool isEmpty = reader.IsEmptyElement; 
     reader.ReadStartElement(); 
     if (isEmpty) 
     { 
      _data = string.Empty; 
     } 
     else 
     {     
      switch (reader.MoveToContent()) 
      { 
       case XmlNodeType.Text: 
       case XmlNodeType.CDATA: 
        _data = reader.ReadContentAsString(); 
        break; 
       default: 
        _data = string.Empty; 
        break; 
      } 
      reader.ReadEndElement(); 
     }       
    } 
+0

Pourriez-vous fournir un exemple de code défaillant? Si je passe en nocdata à votre fonction ReadXml cela fonctionne très bien. –

+0

Son échec pour moi quand l'étiquette n'a pas de balises entourant cdata .. Bien sûr cela a fonctionné pour vous après que vous avez retiré la balise CDATA de l'échantillon que j'ai ci-dessus? Je reçois une erreur lors de l'exécution de reader.ReadEndElement() ... – jvtech

+0

J'ai testé sur un plus simple. Vérifiez ma réponse pour l'échantillon de code. –

Répondre

1

Le code ci-dessous est testé sur les échantillons suivants:

<Data><h1>CHAPTER 2<br/> EDUCATION</h1><P> Analysis paragraph </P></Data> 
<Data>test<h1>CHAPTER 2<br/> EDUCATION</h1><P> Analysis paragraph </P></Data> 
<Data><![CDATA[ <h1>CHAPTER 2<br/> EDUCATION</h1><P> Analysis paragraph </P> ]]></Data> 
<Data></Data> 

j'utiliser à la place un XPathNavigator car il permet retours en arrière.

public void ReadXml(XmlReader reader) 
{ 
    XmlDocument doc = new XmlDocument {PreserveWhitespace = false}; 
    doc.Load(reader); 

    var navigator = doc.CreateNavigator(); 
    navigator.MoveToChild(XPathNodeType.Element); 
    _data = navigator.InnerXml.Trim().StartsWith("&lt;") ? navigator.Value : navigator.InnerXml; 
} 
+0

Cela fait l'affaire. J'ai fini par utiliser Xnode au lieu de XmlDocument, puis sa méthode createNavigator pour obtenir un XPathNavigator à utiliser pour récupérer le innerxml. – jvtech

+0

L'utilisation d'un XmlNode est probablement mieux, et heureux que cela fonctionne. N'hésitez pas à marquer la réponse aussi bien acceptée :) –

+0

Utiliser XmlDocument.Load, puis obtenir XmlNode ne fonctionne pas pour moi. L'exemple de xml dans l'exemple que j'ai donné est juste l'un des nœuds dans les données d'entrée réelles (l'entrée réelle a une structure xml assez complexe). Donc, si j'essaie de faire XmlDocument.Load lors de l'analyse de ce nœud particulier, j'obtiens des erreurs, et je ne peux pas lire plus loin. – jvtech