2012-06-11 3 views
2

Je voudrais écrire quelque chose en C# qui prend Xml et le convertit en texte brut.Xml to Text Convert

<note> 
    <to>Tove</to> 
    <from>Jani</from> 
    <heading>Reminder</heading> 
    <body>Don't forget me this weekend!</body> 
</note> 

deviendrait:

To Tove 
From Jani 
Heading Reminder 
Body don't forget me this weekend! 

Y at-il déjà quelque chose comme ça? et comment pourrais-je faire cela?

Ceci est ruffly juste l'idée im va pour les besoins encore beaucoup de travail:

private void dataGridViewResult_SelectionChanged(object sender, EventArgs e) 
     { 
      if (this.dataGridViewResult.SelectedRows.Count > 0) 
      { 
       XslCompiledTransform xslt = new XslCompiledTransform(); 
       xslt.Load("SQL"); //.xml 

       xslt.Transform("SQL","SQL"); //.xml, .html 
       this.richTextBoxSQL.Text = this.dataGridViewResult.SelectedRows[0].Cells["SQL"].Value.ToString(); 
      } 
     } 
+2

Jetez un coup d'œil à XSLT. Vous pouvez le faire avec un script XSLT et vous pouvez appliquer le script à n'importe quel document XML en utilisant la classe 'XslCompiledTransform'. –

+0

juste essayer de raffiner un exemple de la sortie :), merci – Pomster

+0

J'essaie de convertir une procédure stockée XML, pas vraiment une feuille de style – Pomster

Répondre

3

Quelque chose comme ceci:

XmlDocument doc = new XmlDocument(); 
    doc.LoadXml(your text string); 

    StringBuilder sb = new StringBuilder(); 
    foreach (XmlNode node in doc.DocumentElement.ChildNodes) 
    { 
     sb.Append(char.ToUpper(node.Name[0])); 
     sb.Append(node.Name.Substring(1)); 
     sb.Append(' '); 
     sb.AppendLine(node.InnerText); 
    } 

    Console.WriteLine(sb); 
+0

Cela fonctionne si bien! – Pomster

1

Vous pouvez faire quelque chose comme

string xml = @"<note> 
        <to>Tove</to> 
        <from>Jani</from> 
        <heading>Reminder</heading> 
        <body>Don't forget me this weekend!</body> 
       </note>"; 

    StringBuilder sb = new StringBuilder(); 
    foreach (XElement element in XDocument.Parse(XML-STRING).Descendants("note")) 
    { 
     sb.AppendLine(string.Format("{0} {1}", element.Name, element.Value)); 
    } 
5

Le le script XSLT suivant fera ce que vous voulez:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:template match="*"> 
     <xsl:for-each select="*"> 
      <xsl:value-of select="local-name()"/> 
      <xsl:text> </xsl:text> 
      <xsl:value-of select="."/> 
      <xsl:text> 
</xsl:text> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

Ensuite, vous pouvez appliquer le script en utilisant la classe XslCompiledTransform en tant que tel:

private string transformXml(string sourceXmlText, string xsltText) 
{ 
    XmlDocument sourceXmlDocument = new XmlDocument(); 
    sourceXmlDocument.LoadXml(sourceXmlText); 
    XslCompiledTransform transformer = new XslCompiledTransform(); 
    XmlTextReader xsltReader = new XmlTextReader(new StringReader(xsltText)); 
    transformer.Load(xsltReader); 
    MemoryStream outputStream = new MemoryStream(); 
    XmlWriter xmlWriter = XmlWriter.Create(outputStream, transformer.OutputSettings); 
    transformer.Transform(sourceXmlDocument, null, xmlWriter); 
    outputStream.Position = 0; 
    StreamReader streamReader = new StreamReader(outputStream); 
    return streamReader.ReadToEnd(); 
} 

Il est évidemment plus complexe que les autres solutions personnes ont posté, mais il a l'avantage d'être en mesure de changer facilement la script si vous avez besoin de changer le formatage.

+0

+1 Oui, cela semble super, juste en regardant cette partie: "transformer.Load (xsltFilePath);" , Appeler les procédures stockées sur la base de données, puis vouloir les convertir. – Pomster

+1

@Pomster Ce serait le chemin vers le fichier de script XSLT.Si vous ne voulez pas aller dans un fichier pour obtenir le script, vous pouvez lui donner un XmlReader qui lit le script de la mémoire, à la place. –

+0

Oui ça sonne mieux, alors XmlReader je peux passer Xml, puis le convertir? – Pomster

0

Les réponses données ici fonctionnent parfaitement pour les fichiers XML simples sans attributs. Afin de gérer un XML qui peut contenir à la fois des attributs et des valeurs dans les nœuds, vous avez besoin de quelque chose de plus ... complexe. Ne pas mentionner "éléments de liste" (éléments qui ont le même nom de noeud mais des attributs différents, sous le même groupe, par exemple < Livres> < ID du livre = "10" Auteur = "Me" /> < ID du livre = "20" Auteur = "vous" /> </Livres>). J'avais besoin de convertir des fichiers XML en texte délimité par TAB, et j'ai dû inclure tous les cas. Le code a été testé sur quelques fichiers XML ayant des milliers de nœuds et fonctionne. Les "éléments de liste" sont gérés en ajoutant la valeur "liste" de chaque attribut ou élément à la colonne existante, en utilisant "|" en tant que séparateur. J'espère que cela peut aider les autres qui veulent faire quelque chose de similaire et qui ont besoin d'un point de départ. Si quelqu'un lit ceci et connaît une meilleure façon de le faire, j'aimerais vraiment en entendre parler.

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

public class FileProcessing 
{ 
    static public void ConvertXmlFile(String theFile) 
    { 
     string theExportFile = theFile.Replace(".xml", ".txt"); 
     List<List<String>> theColumns = new List<List<string>>(); 
     List<String> theHeader = new List<string>(); 
     List<String> CurrentDepth = new List<string>(); 
     XmlDocument theXml = new XmlDocument(); 
     try 
     { 
      theXml.Load(theFile); 
     } 
     catch (Exception ex) 
     { 
      //handle as you seem fit. I use an error reporting system that is called here. 
      return; 
     } 
     XmlElement theElement = theXml.DocumentElement; 
     CurrentDepth.Add(theElement.ParentNode.Name);//Start at document level 
     String ItemGroupTag = "";//this stores the element that groups all items(This element represents the complete line) 
     String LastTagName = "";//detect if there is a listitem case(item with same tag appearing in a grouptag having different attribute values). 
     int GroupItemDepth = 0; 
     do 
     { 
      //null can occure on various errors. When it falls bellow the GroupItemDepth, the search is over 
      if (theElement == null || CurrentDepth.Count <= GroupItemDepth) break; 
      String CurrentTagName = theElement.ParentNode.Name + "." + theElement.Name; 
      //only advance if this is not a listitem or the ItemGroupTag 
      if (CurrentDepth[CurrentDepth.Count - 1] == CurrentTagName && LastTagName != CurrentTagName) 
      { 
       LastTagName = CurrentTagName; 
       if (theElement.NextSibling != null) 
       { 
        theElement = (XmlElement)theElement.NextSibling; 
        CurrentDepth[CurrentDepth.Count - 1] = LastTagName; 
        continue; 
       } 

       theElement = (XmlElement)theElement.ParentNode; 
       CurrentDepth.RemoveAt(CurrentDepth.Count - 1);//I stepped one level up 
       continue; 
      } 

      //only check the list until I get the group tag 
      if (ItemGroupTag == "") 
      { 
       XmlNodeList theList = theXml.GetElementsByTagName(theElement.Name); 
       if (theList.Count > 1) 
       { 
        ItemGroupTag = CurrentTagName; 
        GroupItemDepth = CurrentDepth.Count; 
       } 
       else 
       { 
        LastTagName = theElement.ParentNode.Name + "." + theElement.Name; 
        CurrentDepth.Add(LastTagName);//Stepped one level down 
        theElement = (XmlElement)theElement.FirstChild; 
        continue; 
       } 
      } 
      //At this point I am in the GroupItem's entries 
      //Check if the "line" has changed 
      if (CurrentTagName == LastTagName && CurrentTagName == ItemGroupTag) 
      { 
       //It has changed. Make sure all columns have equal number of elements. If not, fill them with empty strings 
       int MaxCount = 0; 

       //First pass, find the number of items that should be in every column. Second pass, only one element apart in all occasions that 
       //the count is not equal. Take in account that a column may appear out of nowhere, as an attribute, and fill it up to date 
       for (int loop = 0; loop < theColumns.Count; loop++) if (theColumns[loop].Count > MaxCount) MaxCount = theColumns[loop].Count; 
       for (int loop = 0; loop < theColumns.Count; loop++) 
       { 
        //A problem will appear in cases that the second entry is a new attribute. 
        if (MaxCount > 2 && theColumns[loop].Count == 1) 
        { 
         while (theColumns[loop].Count != MaxCount) theColumns[loop].Insert(0, ""); 
        } 
        else if (theColumns[loop].Count != MaxCount) theColumns[loop].Add(""); 
       } 
       CurrentDepth.RemoveAt(CurrentDepth.Count - 1);//Remove the last entry of the group item 
      } 
      //Add a column for the tag, if there is none, or find its index, IF, this tag does not have child nodes 
      int theColumnIndex = theHeader.IndexOf(CurrentTagName); 
      if (theColumnIndex == -1 && !theElement.HasChildNodes) 
      { 
       theHeader.Add(CurrentTagName); 
       theColumns.Add(new List<string>()); 
       theColumnIndex = theHeader.Count - 1; 
      } 

      if (theElement.HasAttributes) 
      { 
       XmlAttributeCollection theAttributes = theElement.Attributes; 
       for (int loop = 0; loop < theAttributes.Count; loop++) 
       { 
        theColumnIndex = theHeader.IndexOf(theElement.Name + "." + theAttributes[loop].Name); 
        if (theColumnIndex == -1) 
        { 
         theColumns.Add(new List<String>()); 
         theHeader.Add(theElement.Name + "." + theAttributes[loop].Name); 
         theColumnIndex = theHeader.Count - 1; 
        } 
        if (theAttributes[loop].Value == null) 
        { 
         if (CurrentTagName == LastTagName && CurrentTagName != ItemGroupTag) 
          theColumns[theColumnIndex][theColumns[theColumnIndex].Count - 1] += "|"; 
         else theColumns[theColumnIndex].Add(""); 
        } 
        else 
        { 
         if (CurrentTagName == LastTagName && CurrentTagName != ItemGroupTag) 
          theColumns[theColumnIndex][theColumns[theColumnIndex].Count - 1] += "|" + theAttributes[loop].Value.ToString(); 
         else theColumns[theColumnIndex].Add(theAttributes[loop].Value.ToString()); 
        } 
       } 
      } 
      else if (!theElement.HasChildNodes) 
      { 
       if (theElement.Value == null) 
       { 
        if (CurrentTagName == LastTagName && CurrentTagName != ItemGroupTag) theColumns[theColumnIndex][theColumns[theColumnIndex].Count - 1] += "|"; 
        else theColumns[theColumnIndex].Add("");//empty string for a null value 
       } 
       else 
       { 
        if (CurrentTagName == LastTagName && CurrentTagName != ItemGroupTag) theColumns[theColumnIndex][theColumns[theColumnIndex].Count - 1] += "|" + 
         theElement.Value.ToString(); 
        else theColumns[theColumnIndex].Add(theElement.Value.ToString()); 
       } 
      } 

      LastTagName = CurrentTagName; 
      if (theElement.HasChildNodes) 
      { 
       theElement = (XmlElement)theElement.FirstChild; 
       CurrentDepth.Add(LastTagName);//Went down a level 
      } 
      else if (theElement.NextSibling != null) 
      { 
       theElement = (XmlElement)theElement.NextSibling; 
       //Prevent overwriting a previous group level when a list item occurs 
       if (theElement.ParentNode.Name + "." + theElement.Name == LastTagName && CurrentDepth[CurrentDepth.Count - 1] != LastTagName) 
        CurrentDepth.Add(LastTagName); 
       else CurrentDepth[CurrentDepth.Count - 1] = LastTagName; 
      } 
      else 
      { 
       theElement = (XmlElement)theElement.ParentNode; 
       CurrentDepth.RemoveAt(CurrentDepth.Count - 1);//Went up a Level 
      } 
     } while (theElement != theXml.DocumentElement); 
     //Put Everything together and write them to a file 
     List<String> theLines = new List<string>(); 
     String theLine = ""; 
     for (int loop = 0; loop < theHeader.Count; loop++) theLine += "\t" + theHeader[loop]; 
     if (theLine != "") theLines.Add(theLine.Substring(1)); 

     int aMaxCount = 0; 

     //Do a last check for row count consistency in columns 
     for (int loop = 0; loop < theColumns.Count; loop++) if (theColumns[loop].Count > aMaxCount) aMaxCount = theColumns[loop].Count; 
     for (int loop = 0; loop < theColumns.Count; loop++) 
     { 
      if (aMaxCount > 2 && theColumns[loop].Count == 1) 
      { 
       while (theColumns[loop].Count != aMaxCount) theColumns[loop].Insert(0, ""); 
      } 
      else if (theColumns[loop].Count != aMaxCount) theColumns[loop].Add(""); 
     } 

     for (int loop = 0; loop < theColumns[0].Count; loop++) 
     { 
      theLine = ""; 
      for (int loop1 = 0; loop1 < theColumns.Count; loop1++) theLine += "\t" + theColumns[loop1][loop].Replace('\t', ' '); 
      if (theLine != "") theLines.Add(theLine.Substring(1)); 
     } 

     File.WriteAllLines(theExportFile, theLines.ToArray(), Encoding.UTF8); 
    } 
}