Autor Beitrag
PachN
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Fr 04.03.11 12:10 
Hallo, ich mal wieder :)


Ich bin gerade auf der Suche nach einer Möglichkeit, wie ich "illegal character" in einer XML Datei beseitigen kann.

Problem dabei ist, ich bekomme die XML nur, ich kann also nicht sagen, schickt mir ne saubere XML. Da hab ich keinen Einfluss drauf, muss also mit dem Leben, was ich bekomme.

Ich habe es schon damit versucht:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
//Remove illegal character sequences
            string tmpContents = File.ReadAllText(filePath, Encoding.UTF8);

            string pattern = String.Empty;
            switch (XMLVersion)
            {
                case "1.0":
                    pattern = @"#x((10?|[2-F])FFF[EF]|FDD[0-9A-F]|7F|8[0-46-9A-F]9[0-9A-F])";                   
                    break;
                case "1.1":
                    pattern = @"#x((10?|[2-F])FFF[EF]|FDD[0-9A-F]|[19][0-9A-F]|7F|8[0-46-9A-F]|0?[1-8BCEF])";                    
                    break;
                default:
                    throw new Exception("Error: Invalid XML Version!");
            }

            Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
            if (regex.IsMatch(tmpContents))
            {
                tmpContents = regex.Replace(tmpContents, String.Empty);
                File.WriteAllText(filePath, tmpContents, Encoding.UTF8);
                charactersFound = true;
            }
            tmpContents = string.Empty;



Leider kenne ich mich in Regex nicht wirklich aus und funktionieren tut es auch nicht.

Eingabe XML ist diese: (snippet)

ausblenden XML-Daten
1:
2:
3:
4:
5:
<Song FilePath="C:\Das ist - ein Lied.mp3" FileSize="500144">
  <Display Genre="Other" Color="5678931" Cover="162" Tag="1" />
  <Infos FirstSeen="1012111957" />
  <Comment> < > </Comment>
 </Song>


Wie ihr seht steht in <Comment> "< > " und genau das ist das Problem.
Aus diesem Comment-Tag müsste ich alles rausfiltern, was nicht utf-8 entspricht und auch diese Zeichen.

Habt ihr eine Idee wie ich das hinbekomme?
So wie es jetzt ist, kann ich die XML ja noch nicht mal per .Load() laden, da ich sofort eine Exception bekomme :(


Grüße PachN
Greenberet
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 339
Erhaltene Danke: 20

Win 10
C# (VS 2012), C++ (VS 2012/GCC), PAWN(Notepad++), Java(NetBeans)
BeitragVerfasst: Fr 04.03.11 12:42 
Zeichen wie < > werden mit &lt und &gt ins XML geschrieben.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Fr 04.03.11 12:46 
ausblenden C#-Quelltext
1:
<;					

Oder du ersetzt <Comment>...</Comment> einfach durch <Comment><![CDATA[...]]></Comment>.

_________________
>λ=
PachN Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Fr 04.03.11 14:46 
Hallo und danke für die Antworten.



user profile iconGreenberet hat folgendes geschrieben Zum zitierten Posting springen:
Zeichen wie < > werden mit &lt und &gt ins XML geschrieben.


Leider nicht, wenn ich mir die XML mit einem Editor betrachte steht < > drin. Und das verursacht eine Exception.

user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden C#-Quelltext
1:
<;					

Oder du ersetzt <Comment>...</Comment> einfach durch <Comment><![CDATA[...]]></Comment>.


Auch das fällt leider raus.
Ich brauche sozusagen in den Tag einen "normalen" Text.

Weitere Ideen??


Ich versuche es gerade so:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
private void openXML(string pPath)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(pPath);
            }
            catch (XmlException e)
            {
                ArrayList arrXml = new ArrayList();
                StreamReader reader = new StreamReader(pPath);
                string line;
                int i = 0;
                while ((line = reader.ReadLine()) != null)
                {

                    if (i == (e.LineNumber - 1))
                    {
                        string oldString = line;
                        string newString = line.Remove(e.LinePosition - 11);
                        //line = line.Remove(e.LinePosition - 1, 1);
                        line = line.Replace(oldString, newString);
                    }
                    arrXml.Add(line);
                    i++;
                }
                reader.Close();

                StreamWriter writer = new StreamWriter(pPath,false,Encoding.UTF8);
                foreach (string strLine in arrXml)
                {
                    writer.WriteLine(strLine);
                }
                writer.Dispose();

                openXML(pPath);
            }
        }



Nicht schön, aber funktioniert soweit. Bis auf den Fall, wenn soetwas in der XMl steht:

ausblenden XML-Daten
1:
<Comment><test</Comment>					


Dann macht es mir zu viel weg :(
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Fr 04.03.11 15:38 
user profile iconPachN hat folgendes geschrieben Zum zitierten Posting springen:
Auch das fällt leider raus.
Wie meinen? Du musst doch nur zweimal mit string.Replace über das XML drüberschrubben.

_________________
>λ=
PachN Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Fr 04.03.11 17:54 
Hm ok... aber wie weiß ich dann wo <comment> anfängt, wo der inhalt steht und wo </comment> steht, wenn ich das mit string.replace machen will?

ich müsste ja dann in etwa sowas schreibe:

wenn $string line contains "comment"
dann ersetzte <comment> plus inhalt </comment>
mit <comment>><![CDATA[plus inhalt]]></comment>

Ich weiß ja gar nicht so genau wo "plus inhalt" anfängt und aufhört um mir das raus zu ziehen und in CData zu kapseln :-/

Irgendwie steh ich gerade auf dem Schlauch.


Es grüßt ein verwirrter

PachN
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Fr 04.03.11 18:13 
Ich schrieb schon absichtlich von zwei Aufrufen. Denk nochmal drüber nach, ob du den eigentlichen Inhalt überhaupt erkennen musst.

_________________
>λ=
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Fr 04.03.11 22:22 
Hi,
Du köntest das auch einfach per Regex und der Replace-Methode machen:
ausblenden C#-Quelltext
1:
2:
3:
string replacementXml = 
              Regex.Replace(originalXml, "<Comment>(.+)</Comment>"
              string.Format("<![CDATA[{0}]]>""$1"), RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline);
Aber der Ausdruck geht nur, wenn sich nur ein Comment-Tag in der XML befindet. Ansonsten kommt ziemlicher Quatsch raus. Wenn mehrere Comments enthalten sind, müsstest Du nochmal Hand anlegen...

//edit: wenn ich mir das recht überlege, kann es bestimmt einen oder mehrere Song-Knoten in der XML geben. Und zu jedem kann bzw. gibt es dann auch keinen, einen oder sogar mehere Kommentare. Also ist der ober geschriebene Ausdruck natürlich Quatsch bzw. bringt Dich nicht weiter.

In diesem Fall könntest Du einen mehrfachen Replace mit einen MatchEvaluator machen. Das könnte in Deiem Fall in etwa so aussehen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
string replacementXml = 
                Regex.Replace(originalXml, "<Comment>(?<comment>.+?)</Comment>", MatchReplace,
                              RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline);

//und die Methode MatchReplace:
private string MatchReplace(Match m) 
{
  return string.Format("<Comment><![CDATA[{0}]]></Comment>", m.Groups["comment"]);
}

LG, Marko

Für diesen Beitrag haben gedankt: PachN
PachN Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Mo 07.03.11 14:12 
Hallo,

danke schon mal für die Anregung.
Ich werde es mal versuchen, sobald ich mal wieder dazu komme.


Grüße PachN
PachN Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Di 08.03.11 12:18 
Funktioniert 1 A soweit :)

Könntest du mir auch noch den genau umgekehrten Weg bitte beschreiben?
Ich bekomme das mit den RegEx nicht hin :(

Gruß PachN
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Di 08.03.11 16:08 
Hallo,

also ich will mal nicht so sein. Auch wenn Du, wenn Du denn reguläre Ausdrücke öfters benötigst, diese auch lernen solltest!
ausblenden C#-Quelltext
1:
2:
3:
string x = "<Comment><![CDATA[xxxxx]]></Comment>";
Regex regex = new Regex(@"<Comment><!\[CDATA\[(?<cdata>.+?)\]\]></Comment>");
string comment = regex.Match(x).Groups["cdata"].Value;
LG, Marko

Für diesen Beitrag haben gedankt: PachN
PachN Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Do 10.03.11 17:32 
Hallo Marko,

besten Dank!

Bin nebenher auch schon immer mal wieder dabei Regex zu lernen. Aber ich brauch sie eigentlich so selten, dass ich das bisschen was ich gelernt habe bis dahin schon wieder vergessen hab :)

Aber wer weiß, wenn ich mal mehr weiß, weiß ich vielleicht auch mehr damit anzufangen.


Jedenfalls nochmal dankeschön für die Steilvorlage. Hab es ein wenig abgeändert, aber nun funktioniert es so wie ich es mir vorgestellt habe.


Grüße, PachN
PachN Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Do 10.03.11 20:57 
Hm... irgendwie scheint es doch noch nicht zu funktionieren.

Es versieht zwar alles "Comments" mit den CDATA Tags aber wenn ich danach versuche die XML zu öffnen bekomme
ich trotzdem diese Exception.

ausblenden C#-Quelltext
1:
{"'', hexidezimaler Wert 0x10, ist ein ungültiges Zeichen. Zeile 487, Position 49."}  System.Xml.XmlException					


Obwohl das Zeichen wie man hier schön sieht auch gekapselt ist:

ausblenden XML-Daten
1:
<Comment><![CDATA[                            ]]></Comment>					


(Irgendwie macht es mir hier das zeichen doppelt rein, steht aber nur 1 mal drin)

Wieso????
Kann mir das einer erklären, warum der Parser das trotzdem bemerkt und nicht drüber geht?


Grüße PachN
PachN Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Do 10.03.11 21:48 
Habs schon danke :)