PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Der "Wer hilft mir beim Programmieren"-Thread


hadez16
2015-04-14, 10:22:43
Hallo,

ich hatte eine Abneigung einen eigenen Thread wegen einer kleinen Programmierfrage zu eröffnen und dachte mir somit, dass vielleicht ein Thread Sinn machen würde bei dem man kurze Code-Probleme oder Programmierfragen stellen kann ohne für minimale Dinge einen Thread zu eröffnen.

Ähnlich "Platz für heimatlose Fragen" in der Lounge.

Falls das Prinzip den Admins nicht gefällt kann der Thread natürlich gerne wieder geschlossen werden :)

Ich hätte da ein Problem zu lösen mit C#:

Ich habe einen String


<bla>
<blub>
<text>Ich & Ich</text>
</blub>
</bla>


Diesen will ich als XMLDocument parsen, was ja nicht geht da das UND nicht escaped ist.

Ein SecurityElement.Escape will ich auch nicht, da dann auch die XML-Tags escaped werden. Ich möchte eigentlich nur, dass der InnerText so passt, dass ich den String durch den XML-Prozessor schicken darf.

Ich weiß, dass die Problemlösung eigentlich beim Erzeuger des Strings liegen sollte aber darum geht es nun nicht :)

Jemand eine Idee?

Shink
2015-04-14, 10:52:45
Ich weiß, dass die Problemlösung eigentlich beim Erzeuger des Strings liegen sollte aber darum geht es nun nicht :)

Jemand eine Idee?
Du willst also einen nicht-XML-Text als XML Parsen.
Super Sache.

String-Replace mit Regexp. Wie die aussieht, bleibt als Übung für den Bittstellenden.:freak:

hadez16
2015-04-14, 11:44:58
Du willst also einen nicht-XML-Text als XML Parsen.
Super Sache.

String-Replace mit Regexp. Wie die aussieht, bleibt als Übung für den Bittstellenden.:freak:

Okay...ich habe mir sowas erdacht:


MatchCollection regmatches = Regex.Matches(kaputteXML, @"(?<=>)(.*?)(?=<)");
foreach (Match match in regmatches)
{
kaputteXML = kaputteXML.Replace(match.Value, match.Value.Replace("&", "&amp;").Replace("'", "&apos;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("\"", "&quot;"));
}

RattuS
2015-04-14, 21:59:43
Das ist kein Problem; das ist ein Konflikt. Wenn XML, dann richtig, also hau dem Datenlieferant auf die Finger.

Warum es keine saubere Lösung gibt? Weil du früher oder später auf sowas hier treffen wirst:

<bla>
<blub>
<text>Ich &amp; Ich</text>
</blub>
</bla>

und sowas draus machst:

<bla>
<blub>
<text>Ich &amp;amp; Ich</text>
</blub>
</bla>

Lookbehind und Lookahead haben auch ihre Grenzen. Und denk nur an die ganzen anderen Sonderzeichen. Also viel Spaß mit dem kompletten Unicode-Satz. :uup:


Die Idee des Threads finde ich aber gut. :up:

ezzemm
2015-04-15, 07:07:42
Eine pragmatische Lösung wäre, erst "&amp;" gegen "&" zu tauschen, und anschließend "&" gegen "&amp;". Damit würde man "&amp;amp;" umgehen. Schön ist anders, aber es funktioniert.

Grestorn
2015-04-15, 09:34:48
Eine pragmatische Lösung wäre, erst "&amp;" gegen "&" zu tauschen, und anschließend "&" gegen "&amp;". Damit würde man "&amp;amp;" umgehen. Schön ist anders, aber es funktioniert.

Nein. Überleg mal, was dann aus &lt; werden würde...

Dr.Doom
2015-04-15, 11:02:01
Ich würd' zuerst nach alleinstehenden &-Symbolen ( "...blubb & blobb..." ) suchen und dann amplifizieren.

Alternativ würde ich gar nicht erst versuchen zu reparieren, sondern einfach mit "ungültige Datenquelle, kann Zeile XYZ nicht analysieren"-Ausnahmen um mich werfen.

RattuS
2015-04-16, 00:45:38
Ich würd' zuerst nach alleinstehenden &-Symbolen ( "...blubb & blobb..." ) suchen und dann amplifizieren.
Wer sagt denn, dass es Whitespaces bei einer Und-Verknüpfung geben muss?
Max&Moritz

Richtig wäre dann eher sowas hier:
&(?!([a-zA-Z]+|#[0-9]+|#x[0-9a-fA-F]+);)

ezzemm
2015-04-17, 07:00:28
Nein. Überleg mal, was dann aus &lt; werden würde...

Mein Kommentar ist ja auch nicht als alleinstehende Lösung zu betrachten. Man muß natürlich alle Sonderzeichen die man erwartet entsprechend behandeln. Wenn im XML-File eine URL erwartet ist das natürlich leichter als bei einem Freitext.

Shink
2015-04-17, 08:01:15
Insgesamt kann man natürlich nur verlieren, wenn die Daten Mist sind und man dann XML daraus macht. Die Probleme abseits von "Müller & co k.g." treten sicher erst später auf. Man weiß also nie, wann man fertig ist imo.

hadez16
2015-05-27, 14:58:30
Mal C++

Ich habe eine Funktion die einen String als Konstante übergeben bekommt. Den Wert (CString) möchte ich in der Funktion aber ändern (Replace), was ja nicht geht weil const.

Was ist hier jetzt der richtige Weg?
Ich bin da so eingerostet...


bool myFunction(const CString &wert)
{
int n = wert.Replace(_T("bla"), _T("blub")); //geht ja nicht weil const
...

}


Mir widerstrebt innerlich sowas wie CString neuerWert = wert;int n = neuerWert.Replace(_T("bla"), _T("blub")); weil es in C++ bestimmt 100 Gründe gibt das nicht so zu tun.

Grestorn
2015-05-27, 15:25:39
Du kannst nur auf einer Kopie des Strings arbeiten, nicht auf dem Original. Der ist ja const, und der Sinn dahinter ist, dass Du das Original des Strings, das ja dem Aufrufer Deiner Routine gehört, nicht einfach "unter dessem Hintern" ändern darfst. Der Aufrufer rechnet nicht damit, dass Du seinen String änderst.

Schau Dir dazu auch nochmal die Beschreibung der Konsequenzen an, wenn Parameter per Referenz oder Pointer übergeben werden.

Mosher
2015-05-27, 15:50:45
Die Frage ist, wie dirty die Lösung sein darf.

In C auf µC-Ebene kann man sowas "umgehen", indem man direkt auf die Speicheradressen zugreift. Assembler kann auch helfen.

Mit c++, vermutlich nicht auf µC-Ebene weiß ich gerade nicht, ob es solche Lösungen auch gibt, ich gehe aber eigentlich stark davon aus. Dieses const-Konstrukt ist ja eigentlich nur Compiler-Sache, irgendwo müssen aber auch eine const-Variable im Speicher liegen.

Allerdings kann es dennoch zu massiven Problemen kommen, wenn du es zur Laufzeit schaffst, const-"Variablen" zu ändern, da diese vom Compiler schon beim Kompilieren ausgewertet werden.

Aber auch da gibt es Unterschiede :/

Summa summarum:
Ja, es geht bestimmt "irgendwie", aber leider kann ich Dir gerade mit nichts konkretem kommen. Dafür ist mein Wissen in dem Bereich gerade nicht zuverlässig genug.

Die andere Frage, die sich mir stellt ist allerdings, warum diese Methode mit dieser Signatur existiert und du darin eine const verändern musst.

Ja, ich weiß, vermutlich "ist es halt einfach so", aber mich interessiert es trotzdem. Vielleicht fällt mir ja noch eine andere Lösung ein.

hadez16
2015-05-27, 15:57:50
Ich glaube ich habe mich falsch ausgedrückt.

Ich möchte ja noch nicht unbedingt mal die Quelle ändern, sondern nur den Inhalt darin verändern und weiterverarbeiten, zur Not in einer neuen Variable.

Schick wäre natürlich den Input-Param "Wert" zu nehmen, aber das geht ja nicht.

Eine Kopie in einen neuen String wäre ja bestimmt eine Möglichkeit. Spricht da was dagegen? (mein Edit oben)

Exxtreme
2015-05-27, 15:58:06
const-Variablen würde ich nicht per quick&dirty ändern sondern kopieren und mit der Kopie arbeiten. Es hat nämlich schon seine Gründe warum eine Variable als const deklariert wurde. Ich glaube auch, const-Variablen werden vom Compiler anders optimiert und es kann u.U. krachen wenn mehrere Threads drauf zugreifen.

Und falls es doch unbedingt sein muss diese Variable zu ändern, ich glaube, mit einem Zeiger auf void und Cast auf einen CString ohne const müsste es gehen.

Grestorn
2015-05-27, 16:05:19
Eine Kopie in einen neuen String wäre ja bestimmt eine Möglichkeit. Spricht da was dagegen? (mein Edit oben)

Ja, wie gesagt, einfach eine Kopie des Strings anlegen:

CString kopie(wert)

und dann mit kopie arbeiten. Wenn Du es so machst, ist die Kopie auch nur auf dem Stack der Routine und Du musst Dich nicht ums freigeben kümmern.

/edit: Dein Code ist aber auch ok, ist gleichwertig.

hadez16
2015-07-24, 11:25:03
Mal eine Frage zu C#.

Ich habe eine XSD. Daraus kann ich mir bekanntlich mit XSD.exe eine Klasse generieren und diese nutzen.

Ist es irgendwie möglich, dass ich beispielsweise eine Enumeration innerhalb der XSD erweitern kann OHNE dass ich das Projekt neu komplilieren muss inkl XSD.exe sondern diese Änderung in der XSD beim Start der Applikation zur Verfügung steht, sodass die Klasse aus meiner XSD dann eben über den neuen Wert in der Enum verfügt??

Ich hoffe ihr wisst wie ich meine..."dynamische deserialisierte Klasse aus der XSD"

EDIT: https://msdn.microsoft.com/de-de/library/system.runtime.serialization.xsddatacontractimporter%28v=vs.110%29.aspx
damit dynamisch eine DLL aus meinem Schema erstellen, aus der ich meine Klasse instanziere?
EDIT2: ach ne, da fällt nur eine .cs hintenrunter

Monger
2015-07-25, 12:06:04
Dein Grundproblem ist, dass xsd halt nur eine Datei frisst. Würde es einen Stream fressen, dann wäre das überhaupt kein Ding.

Aber xsd.exe kocht halt auch nur mit Wasser. Schau dir mal folgendes an:

http://mikehadlow.blogspot.de/2007/01/writing-your-own-xsdexe.html

Dann könntest du deine XSD Datei selber laden, die XML Struktur entsprechend anpassen, und erst dann weiterreichen.

Novum
2015-07-27, 17:54:39
Ich glaube ich habe mich falsch ausgedrückt.

Ich möchte ja noch nicht unbedingt mal die Quelle ändern, sondern nur den Inhalt darin verändern und weiterverarbeiten, zur Not in einer neuen Variable.

Schick wäre natürlich den Input-Param "Wert" zu nehmen, aber das geht ja nicht.

Eine Kopie in einen neuen String wäre ja bestimmt eine Möglichkeit. Spricht da was dagegen? (mein Edit oben)
Was an der Kopie besonders langsam ist, ist die allozierung von Heap-Speicher.

Falls du das vermeiden willst hilft nur ein Stack-String, das gibt's aber nicht in der STL.