XDocument System.UriFormatException: 'Invalid URI: The Uri string is too long - c#

I am trying to read the XML in the soapmessage. the XML is 23822 lines.
An exception with System.UriFormatException: 'Invalid URI: The Uri string is too long.' occur.
Below is the code to read the XML response:
XDocument xdoc = XDocument.Load(soapmessage);
var ids = xdoc.Element("FourMonthsAhead1Result")
.Elements("PlantForecastIntervals")
.Elements("<PlantForecastIntervalNode>")
.Select(item => item.Element("IntervalStartTime").Value);
Console.WriteLine(ids);
Below is a small snippet of the response of the XML:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:Body>
<FourMonthsAhead1Response xmlns="http://tempuri.org/">
<FourMonthsAhead1Result xmlns="LSS.solar.webservice">
<PlantDescription xmlns="http://base.datacontract">*PlantName*</PlantDescription>
<PlantForecastIntervalsCount xmlns="http://base.datacontract">2976</PlantForecastIntervalsCount>
<ForecastStartDate xmlns="http://base.datacontract">2021-10-08T13:35:55.912612</ForecastStartDate>
<ForecastEndDate xmlns="http://base.datacontract">2021-10-08T13:35:55.9126123</ForecastEndDate>
<PlantForecastIntervals xmlns="http://base.datacontract">
<PlantForecastIntervalNode>
<IntervalStartTime>2021-10-01T00:00:00</IntervalStartTime>
<IntervalEndTime>2021-10-01T00:15:00</IntervalEndTime>
<IntervalLength>15</IntervalLength>
<ForecastResultParameter>FourMonthsAhead1</ForecastResultParameter>
<ForecastValue>0</ForecastValue>
<ValueUnit>MW</ValueUnit>
</PlantForecastIntervalNode>
<PlantForecastIntervalNode>
<IntervalStartTime>2021-10-01T00:15:00</IntervalStartTime>
<IntervalEndTime>2021-10-01T00:30:00</IntervalEndTime>
<IntervalLength>15</IntervalLength>
<ForecastResultParameter>FourMonthsAhead1</ForecastResultParameter>
<ForecastValue>0</ForecastValue>
<ValueUnit>MW</ValueUnit>
</PlantForecastIntervalNode>
</PlantForecastIntervals>
</FourMonthsAhead1Result>
</FourMonthsAhead1Response>
</s:Body>
</s:Envelope>

Use XDocument.Parse to create XDocument from a content string instead of XDocument.Load, which used to create XDocument from file by specifying its path or uri:
XDocument xDoc;
string soap = File.ReadAllText("H:\\soap.xml");
// Parse used to get data from a string
xDoc = XDocument.Parse(soap);
// Load can be used to get data from specified file
xDoc = XDocument.Load("H:\\soap.xml");
// Load attempt from string content will throw you an error
xDoc = XDocument.Load(soap);

Related

Using Xpath to select single node, when node contains namespace

I have following response for one of my SOAP request.
<?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>
<UploadIsoResponse xmlns="http://localhost:8000/gw/">
<UploadIsoResult>false</UploadIsoResult>
<status>ISO File does not exist</status>
<md5>string</md5>
<days>9/18/2015 12:00:00 AM</days>
</UploadIsoResponse>
</soap:Body>
</soap:Envelope>
And I am using following code to parse it. However I am getting an error Object reference not set to an instance of an object. This is actually because of the resulting null value returned from the xpath. Please help me on parsing single node.
public void fill_response_data(string xml_buffer)
{
string TARGET_NAME_SPACE = "http://localhost:8000/gw/";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml_buffer);
XmlNamespaceManager ns = new XmlNamespaceManager(xmlDoc.NameTable);
ns.AddNamespace("msbld", TARGET_NAME_SPACE);
XmlNode md5_node = xmlDoc.SelectSingleNode("//msbld:UploadIsoResponse/md5", ns);
XmlNode md5_status_node = xmlDoc.SelectSingleNode("//msbld:UploadIsoResponse/status", ns);
txt_md5_checksum.Text = md5_node.InnerText;
txt_status.Text = md5_status_node.InnerText;
}
Exception : System.Xml.XmlDocumentAn unhandled exception of type 'System.NullReferenceException' occurred in IsoGateway.exe
Fixed the issue by adding name space in xpath and below is the updated snippet.
XmlNode md5_node = xmlDoc.SelectSingleNode("//msbld:UploadIsoResponse/msbld:md5", ns);
XmlNode md5_status_node = xmlDoc.SelectSingleNode("//msbld:UploadIsoResponse/msbld:status", ns);

How to working with xml nodes

I have program with response from website in the xml format with namespace.
example program:
string responsedata;//response data from website
//Creat new XMLdoc object for response data
XmlDocument ResponseDataXml = new XmlDocument();
ResponseDataXml.InnerXml= responsedata;
XmlNamespaceManager xnsm = new XmlNamespaceManager(ResponseDataXml.NameTable);
xnsm.AddNamespace("ps","http://example.com/namespace/ps");
//create xml document fro validating DTD
XmlDocument ValidateXml = new XmlDocument();
//select Nodes <ps:results> ... <result>
XmlNodeList NodesResults = ResponseDataXml.SelectNodes("ps:results/result");
foreach (XmlNode node in NodesResults)
{
ValidateXml.InnerText= "";
ValidateXml.InnerText += "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
ValidateXml.InnerText += "<!DOCTYPE SouborN1A SYSTEM \"validate_dtd.dtd\">";
ValidateXml.InnerText+=node.InnerXml;
ValidateXml.Save("validate_temp.xml");
if (validate("validate_temp.xml"))//validate() return true if document is valid
{
Console.WriteLine("Result:" + node.Attributes["id"] + " is valid !!!!!");
// here i can append "result" node in new xml document "Valid_result.xml"
}
else
{
Console.WriteLine("Result:"+ node.Attributes["id"] + "i invalid !!!!!");
// here i can append "result" in new xml document invalid result in to "invalid_result.xml"
}
}
Input postdata:
<ps:report xmlns:ps="example.com.....">
<results xmlns:ps="example.com....." ps:Identifikation="999999">
<result id="11125">
.......
</result>
<result id="1100">
.......
</result>
<result id="111999055">
.......
</result>
<result id="100000">
.......
</result>
</results>
</ps:report>
Please help me... :)
I do not know how to proceed, and work with a given output,
I need mainly validate the item separately and then store in a xml file.
I apologize for my English.
Thanks.
Unfortunately, this question is fairly broad, but generally speaking everything can be done with XML libraries in C#. For example, use the XmlDocument class to create elements and then simply append those elements to the existing nodes.
class Program
{
static void Main(string[] args)
{
var output = new XmlDocument();
output.AppendChild(output.CreateXmlDeclaration("1.0", "utf-8", null));
var xmlns = new XmlNamespaceManager(output.NameTable);
var root = output.CreateElement("ps", "report", "http://example.com/namespace/ps");
var list = output.CreateElement("ps", "results", "http://example.com/namespace/ps");
list.Attributes.Append(output.CreateAttribute("Identifikation"));
list.Attributes[0].Value = "999999";
root.AppendChild(list);
var item = output.CreateElement("ps", "result", "http://example.com/namespace/ps");
item.Attributes.Append(output.CreateAttribute("id"));
item.Attributes[0].Value = "11125";
list.AppendChild(item);
//TODO: Append more validation messages.
output.AppendChild(root);
output.WriteTo(new XmlTextWriter(Console.Out));
System.Console.ReadLine();
}
}
Produces a document like this:
<?xml version="1.0" encoding="utf-8"?>
<ps:report xmlns:ps="http://example.com/namespace/ps">
<ps:results Identifikation="999999">
<ps:result id="11125" />
</ps:results>
</ps:report>

"Root element is missing" exception given when trying to parse XML file

I'm trying to set up parsing for a test XML generated with ksoap2 in Android:
<?xml version="1.0" encoding="utf-8"?>
<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
<v:Header />
<v:Body>
<v:SOAPBODY>
<v:INFO i:type="v:INFO">
<v:LAITETUNNUS i:type="d:string">EI_TUNNUSTA</v:LAITETUNNUS>
</v:INFO>
<v:TOIMINNOT i:type="v:TOIMINNOT">
<v:TOIMINTA i:type="d:string">ASETUKSET_HAKU</v:TOIMINTA>
</v:TOIMINNOT>
<v:SISALTO i:type="v:SISALTO">
<v:KUVA i:type="d:string">AGFAFDGFDGFG</v:KUVA>
<v:MITTAUS i:type="d:string">12,42,12,4,53,12</v:MITTAUS>
</v:SISALTO>
</v:SOAPBODY>
</v:Body>
</v:Envelope>
But seemingly i can't parse it in any way. The exception is always that "Root element is not found" even when it goes through XML-validators like the one at w3schools. If i'm correct the contents of the body shouldn't be an issue when the problem is with root element.
The test code for parsing i try to use in C# is:
using (StreamReader streamreader = new StreamReader(Context.Request.InputStream))
{
try
{
XDocument xmlInput = new XDocument();
streamreader.BaseStream.Position = 0;
string tmp = streamreader.ReadToEnd();
var xmlreader = XmlReader.Create(streamreader.BaseStream);
xmlInput = XDocument.Parse(tmp);
xmlInput = XDocument.Load(xmlreader);
catch (Exception e)
{ }
where the xmlInput = XDocument.Parse(tmp); does indeed parse it to a XDocument, not a navigable one, though. Then xmlInput = XDocument.Load(xmlreader); throws the exception for not having a root element. I'm completely at loss here because i managed to parse and navigate the almost same xml with XMLDocument and XDocument classes before, and i fear i made some changes i didn't notice.
Thanks in advance.
Update: Here's the string tmp as requested :
"<?xml version=\"1.0\" encoding=\"utf-8\"?><v:Envelope xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\" xmlns:c=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:v=\"http://schemas.xmlsoap.org/soap/envelope/\"><v:Header /><v:Body><v:SOAPBODY><v:INFO i:type=\"v:INFO\"><v:LAITETUNNUS i:type=\"d:string\">EI_TUNNUSTA</v:LAITETUNNUS></v:INFO><v:TOIMINNOT i:type=\"v:TOIMINNOT\"><v:TOIMINTA i:type=\"d:string\">ASETUKSET_HAKU</v:TOIMINTA></v:TOIMINNOT><v:SISALTO i:type=\"v:SISALTO\"><v:KUVA i:type=\"d:string\">AGFAFDGFDGFG</v:KUVA><v:MITTAUS i:type=\"d:string\">12,42,12,4,53,12</v:MITTAUS></v:SISALTO></v:SOAPBODY></v:Body></v:Envelope>\r\n"
Update: Even with XDocument.Load(new StreamReader(Context.Request.InputStream, Encoding.UTF8)); the parsing will fail.
I believe you've read to the end of the stream once already, you need to reset the position in the stream again. see: "Root element is missing" error but I have a root element

Converting xml to json with json.net

I try to convert my XML String to Json with Json.Net
In the Json.Net Documentation it says that i have to use this code to convert xml to json:
string xml = #"<person id='1'>
<name>Alan</name>
<url>http://www.google.com</url>
<role>Admin1</role>
</person>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string json = JsonConvert.SerializeXmlNode(doc);
But in my Windows 8 App i can't find the XmlDocument class neither the SerializeXmlNode.
I tried it with these classes and functions:
var result = await response.Content.ReadAsStringAsync();
XDocument xdoc = new XDocument();
xdoc = XDocument.Load(result);
// Parse the JSON Radio data
string jsonText = JsonConvert.SerializeXNode(xdoc);
var radios = JsonArray.Parse(result);
But i get the following error:
An exception of type 'System.ArgumentException' occurred in mscorlib.dll but was not handled in user code
Additional information: Illegal characters in path.
If there is a handler for this exception, the program may be safely continued.
In result i have the correct xml loaded. Starting with:
<?xml version="1.0" encoding="utf-8"?>
<item>...</item>
use XDocument.Parse instead of XDocument.Load which loads the xml from an url

Convert string in xml document

I am getting some xml in a string variable through a wcf webservice. I need to confirm that the string xml I am getting is a valid xml or not.
and I would also like to convert this string to xml document for further processing.
Please let me know how to do it.
How about using XDocument.Parse()
string str =
#"<?xml version=""1.0""?>
<!-- comment at the root level -->
<Root>
<Child>Content</Child>
</Root>";
XDocument doc = XDocument.Parse(str);
Console.WriteLine(doc);
Or if you want to catch the parsing error, use try/catch:
try {
XElement contacts = XElement.Parse(
#"<Contacts>
<Contact>
<Name>Jim Wilson</Name>
</Contact>
</Contcts>");
Console.WriteLine(contacts);
}
catch (System.Xml.XmlException e)
{
Console.WriteLine(e.Message);
}
try to use XElement.Parse :
http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.parse.aspx
I think you can validate the wcf response xml with MessageInspector.MSDN contains a worked example of how this can be accomplished using WCF MessageInspectors

Categories