2016-10-04 3 views
0

I wurde mit einem String-Variable mit folgendem Inhalt gegeben:Ersetzen Sie einige Zeichen in einem String (XML-Format)

<main> 
<Title title="Hello World" /> 
<Content content="bla bla bla... by <1% to ??? on other bla bla...." /> 
</main> 

Diese Saite wird schließlich zu einer gespeicherten Prozedur für XQuery übergeben.

Wie Sie, wird der Inhalt von „Inhalt“ sehen kann, enthält die char „<“, die, wenn ich versuche, in Stored Procedure zu analysieren, senden Sie es mit einem Fehler.

Meine Frage ist, wie die "<" in & lt umzuwandeln; (in diesem Fall < 1% bis & lt; 1%) in einer effizienten Weise.

Ich möchte andere "<" beibehalten, wie es ist.

Tks

+1

Dies scheint kein gültiges XML zu sein. –

+1

'' ist kein gültiger XML-Code, da keine anonymen Attribute vorhanden sind. Meinten Sie stattdessen " foo"? – Dai

+0

Hallo, ich habe die ursprünglichen Codes aktualisiert ... es sollte sein als Trowa

Antwort

1

Da Sie Ihre Frage aktualisiert haben, um zu zeigen, dass Sie mit XML zu tun haben, aber die uncodierten Werte in Attributwerten sind, nicht #text Knoten, dann macht es etwas einfacher, extrahieren Sie einfach den Attributwert mit einem ähnlichen Ansatz zu meinem vorherigen antworte, verwende dann eine Bibliotheksfunktion, um sie zu berechtigen, und gib sie dann aus.

Beachten Sie, dass CDATA nur für #text gilt, keine Attribute.

String doc = 
@"<main> 
<Title title=""Hello World"" /> 
<Content content=""bla bla bla... by <1% to ??? on other bla bla...."" /> 
</main>"; 

Int32 contentOpenStart = doc.IndexOf("<Content"); 
Int32 contentAttribContentValueStart = doc.IndexOf("content=\"", contentOpenStart) + "content=\"".Length; 
Int32 contentAttibContentValueEnd = doc.IndexOf("\"", contentAttribContentValueStart); 

String attributeValueOld = doc.Substring(contentAttribContentValueStart, contentAttibContentValueEnd); 
String attributeValueNew = System.Net.WebUtility.HtmlEncode(attributeValueOld); 

String doc2 = String.Concat(
    doc.Substring(0, contentAttribContentValueStart); 
    attributeValueNew, 
    doc.Substring(contentAttibContentValueEnd); 
); 

doc2 enthält dann den festen Attributwert.

Beachten Sie, dass HtmlEncode mit Hilfe von HTML-Codierung von Entitäten durchzuführen ist nicht ganz korrekt in XML, als der Satz von XML-Entitäten ist viel kleiner als HTML ist - in der Tat, XML ist nur mit &amp;, &gt;, &lt;, &quot; und &apos; , alle anderen Werte sollten im Dokument als rohe/native Zeichen enthalten sein.

+0

Gute Idee für Ihre vorgeschlagene Lösung, ich habe es geschafft, eine Lösung durch geringfügige Anpassung Ihrer Codes zu konstruieren. – Trowa

0

(Diese Antwort beruht auf der Annahme, Sie mit strukturell korrekter XML zu tun haben, nur mit nicht codierten Einheiten in #text Knoten - diese Antwort gilt nicht, wenn Ihre Eingabedaten wirklich wie <Title="foo" /> sehen - das ist überhaupt kein XML)

Wenn ich Ihr Problem richtig verstehe, haben Sie ein XML-Dokument in einer String Instanz, die nicht ordnungsgemäß maskierte/berechtigte Sonderzeichen enthält, die Sie von einem normalen XML-Parser zum Lesen des Dokuments verhindert.

Wenn Sie mit einem XML-kompatiblen System arbeiten, können Sie <![DATA[ verwenden und müssen dann nicht versuchen, den Inhalt des Elements <Content> zu verarbeiten. Der Trick besteht dann darin, die CDATA-Begrenzer einzufügen.

Während oft gesagt wird, dass man keinen regulären Ausdruck verwenden kann, um XML zu analysieren (da XML kein Regular Language ist), können Sie die grammatischen Regeln von XML nutzen, um Tags zu extrahieren und zu identifizieren.

Also, wenn Sie dies:

<Content someAttribute="someValue"> 
reduce sales by <1% in order to ensure that profit > loss 
</Content> 

Dann können Sie dies tun:

String doc = @"<main><Title..."; 
Int32 contentOpenStart = doc.IndexOf("<Content"); 
Int32 contentOpenEnd = doc.IndexOf(">", contentOpenStart); 

Int32 contentCloseStart = doc.IndexOf("</Content>", contentOpenEnd); 

Dieser Code dann sagt uns die locatations der Winkel-Klammern der <Content> zwei Tags des Elements, mit die können wir die CDATA Trennzeichen einfügen:

String newDocument = String.Concat(
    doc.Substring(0, contentOpenEnd + 1), // "<main>...<Content...>" 
    "<![CDATA[", 
    doc.Substring(contentOpenEnd + 1, contentCloseStart), 
    "]]>", 
    doc.Substring(contentCloseStart) "</Content>..." 
); 

newDocument ist dann das:

<Content someAttribute="someValue"><![CDATA[ 
reduce sales by <1% in order to ensure that profit > loss 
]]></Content> 

... was ist gültig XML.

+0

hi @ Dai, tks für den Kommentar. Das Problem besteht darin, dass der Wert innerhalb des Attributs des Tags und nicht in seinem Inhalt liegt. Anstatt also: Verkäufe um <1% zu reduzieren, um sicherzustellen, dass der Profit> Verlust ist, habe ich: Wie kann ich die Codes entsprechend anpassen? Können wir CDATA auch als Attribut verwenden? – Trowa

Verwandte Themen