41 votes

Remplacer le texte dans XamlPackage

J'ai du texte dans une RichTextBox. Ce texte contient des balises, par exemple : [@TagName !]. Je veux remplacer ces balises par des données provenant d'une base de données sans perdre le formatage (polices, couleurs, images, etc.). J'ai créé une méthode :

 void ReplaceTagsWithData(FlowDocument doc)
    {
        FileStream fs = new FileStream("tmp.xml", FileMode.Create);
        TextRange trTextRange = 
            new TextRange(doc.ContentStart, doc.ContentEnd);

        trTextRange.Save(fs, DataFormats.Xaml);
        fs.Dispose();
        fs.Close();

        StreamReader sr = new StreamReader("tmp.xml");

        string rtbContent = sr.ReadToEnd();

        MatchCollection mColl = 
            Regex.Matches(rtbContent, 
                          string.Format(@"\{0}+[a-zA-Z]+{1}", 
                          prefix, 
                          postfix));

        foreach (Match m in mColl)
        {
            string colname = 
                m.Value.Substring(prefix.Length, 
                   (int)(m.Value.Length - (prefix.Length + postfix.Length)));

            rtbContent = rtbContent.Replace(m.Value.ToString(), 
                                            dt.Rows[0][colname].ToString());
        }

        rtbEdit.Document = 
            new FlowDocument(
                (Section)XamlReader.Load(
                    XmlReader.Create(new StringReader(rtbContent))));
        sr.Dispose();
        sr.Close();
    }

Il est assez bon mais il supprime les images du contenu. Je sais que je devrais utiliser XamlPackage au lieu de Xaml mais alors je ne peux pas l'obtenir en texte brut. Existe-t-il une autre solution pour cela ?

Merci pour les réponses. ;)

[EDIT : 13-02-2012 02:14(am)]

Ma solution de travail :

    void ReplaceTagsWithData(RichTextBox rtb)
{
    FlowDocument doc = rtb.Document;

    FileStream fs = new FileStream("tmp", FileMode.Create);
    TextRange trTextRange = new TextRange(doc.ContentStart, doc.ContentEnd);
    trTextRange.Save(fs, DataFormats.Rtf);
    fs.Dispose();
    fs.Close();

    StreamReader sr = new StreamReader("tmp");
    string rtbContent = sr.ReadToEnd();
    sr.Dispose();
    sr.Close();

    MatchCollection mColl = 
        Regex.Matches(rtbContent, 
                      string.Format(@"\{0}+[a-zA-Z]+{1}", 
                      prefix, 
                      postfix));

    foreach (Match m in mColl)
    {
        string colname = 
            m.Value.Substring(prefix.Length, 
                (int)(m.Value.Length - (prefix.Length + postfix.Length)));

        rtbContent = rtbContent.Replace(m.Value.ToString(), 
                                        dt.Rows[0][colname].ToString());
    }
    MemoryStream stream = 
        new MemoryStream(ASCIIEncoding.Default.GetBytes(rtbContent));
    rtb.SelectAll();
    rtb.Selection.Load(stream, DataFormats.Rtf);

}

Ce n'est peut-être pas le meilleur, mais il fonctionne correctement.

Il a été résolu. Mais je ne peux pas poster la solution car elle se trouve sur le serveur de la société auquel je ne peux plus accéder.

1voto

Miguel Points 71

Vous pouvez utiliser le moteur Razor pour faire ce que vous voulez dans le domaine des modèles. Vous pouvez télécharger à partir de nuget ( http://www.nuget.org/packages/RazorEngine ) et sans aucune configuration, vous pouvez utiliser la syntaxe Razor pour le faire. Par exemple, votre modèle peut être le suivant :

<Window x:Class="<class>"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="@Model.Title"
        Icon="@Model.Icon">
  <Grid>    
  </Grid>
</Window>

Note : les @Model.Title et @Model.Icon proviennent de Razor.

En fait, j'utilise RazorEngine pour toutes mes tâches de modélisation : Email, génération de rapports à la volée (rdlc), etc...

0voto

ChrisF Points 143

La Regex que vous utilisez est gourmande et correspondrait à tout ce qui se trouve entre le début d'un token et la fin du suivant. Changez-la en @"\{0}[a-zA-Z]+?{1}" pour une meilleure correspondance.

De même, l'utilisation de la surcharge de Regex.Replace qui prend un lambda serait un code plus propre.

0voto

user1998368 Points 26

Vous pouvez utiliser Aspose.dll. Il y a un forum complet / des exemples et des documents Remplacer un texte basé sur une expression régulière avec aspose.dll

-2voto

Ali Points 20

Essayez d'utiliser la méthode Regex.Replace. Vous pouvez trouver la référence à cette méthode dans MSDN http://msdn.microsoft.com/en-us/library/xwewhkd1.aspx

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X