I am trying to replace within a string
<?xml version="1.0" encoding="UTF-8"?>
<response success="true">
<output><![CDATA[
And
]]></output>
</response>
with nothing.
The problem I am running into is the characters <> and " characters are interacting within the replace. Meaning, it's not reading those lines as a full string all together as one but breaking the string when it comes to a <> or ". Here is what I have but I know this isn't right:
String responseString = reader.ReadToEnd();
responseString.Replace(#"<<?xml version=""1.0"" encoding=""UTF-8""?><response success=""true""><output><![CDATA[[", "");
responseString.Replace(#"]]\></output\></response\>", "");
What would be the correct code to get the replace to see these lines as just a string?
A string will never change. The Replace method works as follows:
string x = "AAA";
string y = x.Replace("A", "B");
//x == "AAA", y == "BBB"
However, the real problem is how you handle the XML response data.
You should reconsider your approach of handling incoming XML by string replacement. Just get the CDATA content using the standard XML library. It's as easy as this:
using System.Xml.Linq;
...
XDocument doc = XDocument.Load(reader);
var responseString = doc.Descendants("output").First().Value;
The CDATA will already be removed. This tutorial will teach more about working with XML documents in C#.
Given your document structure, you could simply say something like this:
string response = #"<?xml version=""1.0"" encoding=""UTF-8""?>"
+ #"<response success=""true"">"
+ #" <output><![CDATA["
+ #"The output is some arbitrary text and it may be found here."
+ "]]></output>"
+ "</response>"
;
XmlDocument document = new XmlDocument() ;
document.LoadXml( response ) ;
bool success ;
bool.TryParse( document.DocumentElement.GetAttribute("success"), out success) ;
string content = document.DocumentElement.InnerText ;
Console.WriteLine( "The response indicated {0}." , success ? "success" : "failure" ) ;
Console.WriteLine( "response content: {0}" , content ) ;
And see the expected results on the console:
The response indicated success.
response content: The output is some arbitrary text and it may be found here.
If your XML document is a wee bit more complex, you can easily select the desired node(s) using an XPath query, thus:
string content = document.SelectSingleNode( #"/response/output" ).InnerText;
Related
In my code I'm creating a new xml file with linq to xml and I have a specific format of xml that I'm trying to put into the xml file on creation. However, when I put the string variable in it gives the error "non white space characters cannot be added to content." How would I correctly add that string value to the xml file?
string firstPart = #"<?xml version=""1.0"" encoding=""utf-8""?>
< wiidisc version = ""1"" >
< id game = ""RMCE"" disc = ""0"" version = ""0"" >
</ id > ";
XDocument doc = new XDocument(firstPart);
doc.Save(riivolutionXmls + #"\" + xmlFileName + ".xml");
This isn't valid XML, you're missing a closing tag for wiidisc.
Also I don't think you can use the constructor to create an XDocument from a string, I think you have to use the XDocument.Parse method:
https://learn.microsoft.com/en-us/dotnet/api/system.xml.linq.xdocument.parse?view=netframework-4.7.2#System_Xml_Linq_XDocument_Parse_System_String_
I have an XML which is passes as a string variable to me. I want to get the value of specific tags from that XML. Following is the XML I have and what I'm trying to achieve:
<code>
string xmlData = #"
<HEADER>
<TYPE>AAA</TYPE>
<SUBTYPE>ANNUAL</SUBTYPE>
<TYPEID>12345</TYPEID>
<SUBTYPEID>56789</SUBTYPEID>
<ACTIVITY>C</ACTION>
</HEADER>";
var typeId = data.Split("<TYPEID>")[0]; //Requirement
var activity = data.Split("<ACTIVITY>")[0]; //Requirement
</code>
I know string.Split(); doesn't work here as it requires a single character only. Other alternate is to use regex which seems a bit threatening to me. Although I have tried to work with it but doesn't getting the desired result. Can someone help with the regex code?
You should have used XML Parsing to get the values but since you are trying split to split a string from a string and not char you can choose
string typeId = xmlData.Split(new string[] { "<TYPEID>" }, StringSplitOptions.None)[1];
string typeIdVal = typeId.Split(new string[] { "</TYPEID>" }, StringSplitOptions.None)[0];
and it looks very neat and clean with XML Parsing
XmlDocument xmlDoc= new XmlDocument();
xmlDoc.Load("yourXMLFile.xml");
XmlNodeList XTypeID = xmlDoc.GetElementsByTagName("TYPEID");
string TypeID = XTypeID[0].InnerText;
You can also choose SubString like
string typeidsubstr = xmlData.Substring(xmlData.IndexOf("<TYPEID>") + 8, xmlData.IndexOf("</TYPEID>") - (xmlData.IndexOf("<TYPEID>") + 8));
I used +8 because the length of <TYPEID> is 8 you can also choose it string.length to evaluate the result.
You can use XML Linq objects to parse these.
NB: There is a typo in the ACTIVITY element, the closing tag should be /ACTIVITY, not /ACTION! (I've corrected below)
string xmlData = #"<HEADER>
<TYPE>AAA</TYPE>
<SUBTYPE>ANNUAL</SUBTYPE>
<TYPEID>12345</TYPEID>
<SUBTYPEID>56789</SUBTYPEID>
<ACTIVITY>C</ACTIVITY>
</HEADER>";
var doc = XDocument.Parse(xmlData);
var typeId = doc.Root.Elements("TYPEID").First().Value;
var activity = doc.Root.Elements("ACTIVITY").First().Value;
My xamarin mobile app consumes soap service, when i make a login request the response returned has both Json and xml. I am interested only in the json string. Can any one tell me the way to parse the following response.
[{"Result":"true","HasError":false,"UserMsg":null,"ErrorMsg":null,"TransporterID":"327f6da2-d797-e311-8a6f-005056a34fa8"}]
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><LoginResponse xmlns="http://tempuri.org/" /></soap:Body></soap:Envelope>
You can use the Substring method as follows:
string response = "<<The response you got>>";
string jsonResponse = response.Substring(0, response.IndexOf("<?"));
The 0 is the starting index (when to start extracting the substring) and the IndexOf will return the index of <? which is the start of the XML part of the response. You can read about the Substring Method here.
Therefore, you have filtered the JSON response from the whole string. (For a how-to parse JSON data, check this answer).
String.IndexOf will give you the index of the xml part, then you can use String.Substring:
string str = #"[{ ""Result"":""true"",""HasError"":false,""UserMsg"":null,""ErrorMsg"":null,""TransporterID"":""327f6da2-d797-e311-8a6f-005056a34fa8""}]
<? xml version = ""1.0"" encoding = ""utf-8"" ?>< soap : Envelope xmlns: soap = ""http://www.w3.org/2003/05/soap-envelope"" xmlns: xsi = ""http://www.w3.org/2001/XMLSchema-instance"" xmlns: xsd = ""http://www.w3.org/2001/XMLSchema"" >< soap:Body >< LoginResponse xmlns = ""http://tempuri.org/"" /></ soap:Body ></ soap:Envelope >";
string json = str.Substring(0, str.IndexOf("<? xml"));
Console.WriteLine(json); // [{ "Result":"true","HasError":false,"UserMsg":D":"327f6da2-d797-e311-8a6f-005056a34fa8"}]
I am having a input stream which is generated when I upload a file(XML Type). I need the XML data at code behind. I am having the xml data in string by using
StreamReader stream = new StreamReader(Request.InputStream);
string x = stream.ReadToEnd();
It also contains the following data at the start of the string
------WebKitFormBoundary8na5dBbHc4ydfxVU
Content-Disposition: form-data; name="MyFile"; filename="Test 123.vfc"
Content-Type: application/octet-stream
at the end of the string
------WebKitFormBoundary8na5dBbHc4ydfxVU--
This data is not required for me. Please help me in getting the right XML String.
First you can remove the first three lines and last line from your string.
int n = 3;
string[] lines = str.Split(Environment.NewLine.ToCharArray()).Skip(n).ToArray();
string output = string.Join(Environment.NewLine, lines);
output = output.Remove(str.LastIndexOf(Environment.NewLine));
In your XML string if you don't have a root node then add it like following.
string xmlTxt = "<ROOT>" + xmlString + "</ROOT>";
If you have a root node skip above. For a well format XML string you can just use below code
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.InnerXml = xmlTxt;
This question already has answers here:
Best way to encode text data for XML
(13 answers)
Closed 2 years ago.
I have a web service that returns an xml string as results. The return string is in this format:
<ReturnValue>
<ErrorNumber>0
</ErrorNumber>
<Message>my message</Message>
</ReturnValue>
The data that I want to insert into the "message" tag is a serialized version of a custom object. The serialized format of that object contains xml and namespace declarations post serialization. When that gets thrown into the "message" tag of my return xml string, XmlSpy says that it's not well-formed. How should I get rid of the namespace declarations, or is there a different way to imbed a serialized object into an xml string?
Wrap the string in CDATA like so:
<![CDATA[your xml, which can be multi-line]]>
CDATA will inform a validator to treat the CDATA contents as ignored text. It's often the most expedient way to embed XML (or taggy non-XML content) as a string. You can run into problems if your embedded XML contains its own CDATA, but otherwise it's a simple fix.
Just make sure that your <Message> XML is encoded so that <, >, ", and & show up as <, >, " and &, respectively.
There are few built-in ways to encode the characters:
string message = System.Web.HttpUtility.HtmlEncode(serializedXml);
string message = System.Security.SecurityElement.Escape(serializedXml);
Using an XmlTextWriter to do the work for you
Use CDATA to wrap your XML
Also, this is probably a duplicate of:
Best way to encode text data for XML
Think of XML as a document not a string.
Create a node named "wrapper", and store the content of your file in it as a Base64 encoded string. The results will look like this.
<ReturnValue>
<ErrorNumber>0</ErrorNumber>
<Message>my message</Message>
<wrapper type="bin.base64">PD94bWwgdmVyc2lvbj0iMS4wIj8+PHhzbDpzdHlsZXNoZWV0IHZ
lcnNpb249IjEuMCIgeG1sbnM6eHNsPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L1hTTC9UcmFuc2Zvcm0
iIHhtbG5zOm1zeHNsPSJ1cm46c2NoZW1hcy1taWNyb3NvZnQtY29tOnhzbHQiPjx4c2w6b3V0cHV0IG1
ldGhvZD0ieG1sIiAvPjx4c2w6dGVtcGxhdGUgbWF0Y2g9Ii8iPjwveHNsOnRlbXBsYXRlPjwveHNsOnN
0eWxlc2hlZXQ+</wrapper>
</ReturnValue>
The following code shows how to add the wrapper, encode the content. Then it reverses the process to show that it all "works".
Using Base64 in XML has a number of other applications as well. For example embedding images, or other documents in XML content.
using System;
using System.IO;
using System.Xml;
public class t
{
static public string EncodeTo64(string toEncode) {
byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
return returnValue;
}
static public string DecodeFrom64(string encodedData) {
byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
string returnValue = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
return returnValue;
}
public static void Main() {
try {
//Create the XmlDocument.
XmlDocument doc = new XmlDocument();
doc.LoadXml( #"
<ReturnValue>
<ErrorNumber>0</ErrorNumber>
<Message>my message</Message>
</ReturnValue>
");
XmlNode nodeMessage = doc.SelectSingleNode( "/ReturnValue/Message" );
if( nodeMessage != null ) {
XmlDocument docImport = new XmlDocument();
docImport.Load( "docwithnamespace.xml" );
// create a wrapper element for the file, then import and append it after <Message>
XmlElement nodeWrapper = (XmlElement)doc.CreateElement( "wrapper" );
nodeWrapper.SetAttribute( "type", "bin.base64" );
nodeWrapper = (XmlElement)doc.ImportNode( nodeWrapper, true );
XmlNode ndImport = nodeMessage.ParentNode.AppendChild( nodeWrapper.CloneNode( true ) );
ndImport.InnerText = EncodeTo64( docImport.OuterXml );
doc.Save( "wrapperadded.xml" );
// Next, let's test un-doing the wrapping
// Re-load the "wrapped" document
XmlDocument docSaved = new XmlDocument();
docSaved.Load( "wrapperadded.xml" );
// Get the wrapped element, decode from base64 write to disk
XmlNode node = doc.SelectSingleNode( "/ReturnValue/wrapper" );
if( node != null ) {
// Load the content, and save as a new XML
XmlDocument docUnwrapped = new XmlDocument();
docUnwrapped.LoadXml( DecodeFrom64( node.InnerText ) );
docUnwrapped.Save( "unwrapped.xml" );
Console.WriteLine( "Eureka" );
}
}
} catch( Exception e ) {
Console.WriteLine(e.Message);
}
}
}