Create XML using Linq to XML and arrays - c#

I am using Linq To XML to create XML that is sent to a third party. I am having difficulty understanding how to create the XML using Linq when part of information I want to send in the XML will be dynamic.
The dynamic part of the XML is held as a string[,] array. This multi dimensional array holds 2 values.
I can 'build' the dynamic XML up using a stringbuilder and store the values that were in the array into a string variable but when I try to include this variable into Linq the variable is HTMLEncoded rather than included as proper XML.
How would I go about adding in my dynamically built string to the XML being built up by Linq?
For Example:
//string below contains values passed into my class
string[,] AccessoriesSelected;
//I loop through the above array and build up my 'Tag' and store in string called AccessoriesXML
//simple linq to xml example with my AccessoriesXML value passed into it
XDocument RequestDoc = new XDocument(
new XElement("MainTag",
new XAttribute("Innervalue", "2")
),
AccessoriesXML);
'Tag' is an optional extra, it might appear in my XML multiple times or it might not - it's dependant on a user checking some checkboxes.
Right now when I run my code I see this:
<MainTag> blah blah </MainTag>
&lt ;Tag&gt ;&lt ;InnerTag&gt ; option1="valuefromarray0" option2="valuefromarray1" /&gt ;&lt ;Tag/&gt ;
I want to return something this:
<MainTag> blah blah </MainTag>
<Tag><InnerTag option1="valuefromarray0" option2="valuefromarray1" /></Tag>
<Tag><InnerTag option1="valuefromarray0" option2="valuefromarray1" /></Tag>
Any thoughts or suggestions? I can get this working using XmlDocument but I would like to get this working with Linq if it is possible.
Thanks for your help,
Rich

Building XElements with the ("name", "value") constructor will use the value text as literal text - and escape it if necessary to achieve that.
If you want to create the XElement programatically from a snippet of XML text that you want to actually be interpreted as XML, you should use XElement.Load(). This will parse the string as actual XML, instead of trying to assign the text of the string as an escaped literal value.
Try this:
XDocument RequestDoc = new XDocument(
new XElement("MainTag",
new XAttribute("Innervalue", "2")
),
XElement.Load(new StringReader(AccessoriesXML)));

Related

Reading more json strings from one file

I've got two different json files and would like to merge them and read json strings from one file.
{"ipAddress":"1.1.1.1","port":80, "protocol":"http"}
{"ipAddress":"1.1.1.1", "domainName":"domain.com"}
I tried something, but it still doesn't work properly. I tried array and also the following structure:
{"jsonString1": {"ipAddress":"1.1.1.1","port":80, "protocol":"http"},
"jsonString2": {"ipAddress":"1.1.1.1", "domainName":"domain.com"}}
Not sure if the structure is correct. I just need to get "jsonString1", "jsonString2" separately so I don't need to use more json files.
Your 1st fragment is non standard (effectively, not JSON).
Your 2nd IS standard, but is an object, not an array.
If you want an array, use an array:
[{"ipAddress":"1.1.1.1","port":80, "protocol":"http"},
{"ipAddress":"1.1.1.1", "domainName":"domain.com"}]
Alternatively, if you want to use your 2nd version (which is an object), you can access the 2 "sub-objects" by keys: myObj.jsonString1, myObj.jsonString2. BTW, A better name would be "Obj1" & "Obj2" since these are not strings, they're actual objects.
Use JSON Array to keep those files merged.For example
Conside,You have an JSON array for URL then and you want to print it in a paragraph then
<p id="url"></p>
declare a variable like this
var URL=[{"ipAddress":"1.1.1.1","port":80, "protocol":"http"},
{"ipAddress":"1.1.1.1", "domainName":"domain.com"}]
you can access these array by using
document.getElementById("url").innerHTML =
URL[0].ipAddress+ " " + URL[0].port+ " " +URL[0].protocol;
You can get the array values by using the index values
Thank you. I have finally used this syntax:
json:
{"jsonString1": {"ipAddress":"1.1.1.1","port":80, "protocol":"http"},
"jsonString2": {"ipAddress":"1.1.1.1", "domainName":"domain.com"}}
read the string using this command:
var jsonObject = JObject.Parse(jsonData);
string value = jsonObject["jsonString1"].ToString();

Trouble with hexadecimap chars in XML data

I am trying to create an XML document using LINQ.
XElement element = new XElement("ManufacturerName", supplierName);
XDocument doc = new XDocument(element);
doc.Save("Sample.xml");
The supplierName has some special char at the end whose hexadecimal value is 0x1f.
This will not allow to save the document.
For this instance its this value for others it may be different.
So is there a way to remove any / all special chars?
Thanks in advance.

Fill in values in XML Template

I have xml templates stored in files where there are values to be filled are written as lets say following for example
<customers>
<customer>
<name><%=user.name%></name>
<street><%=user.address.street%></street>
</customer>
</customers>
I will have user object filled in and will load this xml in string . Is there any easy way to replace related values in entire file easily ? Please consider that above is just sample and XML is really complicated with lot of constants in it and I cant use XML serialization to convert object in to XML .
Thanks
A simple regex can help here
var newXml = Regex.Replace(xml, "<%=(.+?)%>", m => MyFxn(m.Groups[1].Value));
//replace this function with yours which returns the real values. It's
//just a demo....
string MyFxn(string s)
{
var dict = new Dictionary<string, string>(){
{"user.name","name1"},
{"user.address.street","street1"}
};
return dict[s];
}
Use regex to find your data-binding expressions and replace them with values obtained using DataBinder.Eval (in ASP.NET) or through reflection from corresponding properties of your object (http://programmersunlimited.wordpress.com/2010/06/19/reflection-get-property-value-from-path/).

How to iterate over xml using linq2xml or Xquery

I have an incoming file with data as
<root><![CDATA[<defs><elements>
<element><item>aa</item><int>1</int></element>
<element><item>bb</item><int>2</int></element>
<element><item>cc</item><int>3</int></element>
</elements></defs>]]></root>
writing multiple foreach( xElement x in root.Elements ) seems superfluous !
looking for a less verbose method preferably using C#
UPDATE - yes - the input is in a CDATA, rest assured it's not my design and i have ZERO control over it !
Assuming that nasty CDATA section is intentional, and you're only interested in the text content of your leaf elements, you can do something like:
XElement root = XElement.Load(yourFile);
var data = from element in XElement.Parse(root.Value).Descendants("element")
select new {
Item = element.Elements("item").First().Value,
Value = element.Elements("int").First().Value
};
That said, if the code that generates your input file is under your control, consider getting rid of the CDATA section. Storing XML within XML that way is not the way to go most of the time, as it defeats the purpose of the markup language (and requires multiple parser passes, as shown above).

How do I work with an XML tag within a string?

I'm working in Microsoft Visual C# 2008 Express.
Let's say I have a string and the contents of the string is: "This is my <myTag myTagAttrib="colorize">awesome</myTag> string."
I'm telling myself that I want to do something to the word "awesome" - possibly call a function that does something called "colorize".
What is the best way in C# to go about detecting that this tag exists and getting that attribute? I've worked a little with XElements and such in C#, but mostly to do with reading in and out XML files.
Thanks!
-Adeena
Another solution:
var myString = "This is my <myTag myTagAttrib='colorize'>awesome</myTag> string.";
try
{
var document = XDocument.Parse("<root>" + myString + "</root>");
var matches = ((System.Collections.IEnumerable)document.XPathEvaluate("myTag|myTag2")).Cast<XElement>();
foreach (var element in matches)
{
switch (element.Name.ToString())
{
case "myTag":
//do something with myTag like lookup attribute values and call other methods
break;
case "myTag2":
//do something else with myTag2
break;
}
}
}
catch (Exception e)
{
//string was not not well formed xml
}
I also took into account your comment to Dabblernl where you want parse multiple attributes on multiple elements.
You can extract the XML with a regular expression, load the extracted xml string in a XElement and go from there:
string text=#"This is my<myTag myTagAttrib='colorize'>awesome</myTag> text.";
Match match=Regex.Match(text,#"(<MyTag.*</MyTag>)");
string xml=match.Captures[0].Value;
XElement element=XElement.Parse(xml);
XAttribute attribute=element.Attribute("myTagAttrib");
if(attribute.Value=="colorize") DoSomethingWith(element.Value);// Value=awesome
This code will throw an exception if no MyTag element was found, but that can be remedied by inserting a line of:
if(match.Captures.Count!=0)
{...}
It gets even more interesting if the string could hold more than just the MyTag Tag...
I'm a little confused about your example, because you switch between the string (text content), tags, and attributes. But I think what you want is XPath.
So if your XML stream looks like this:
<adeena/><parent><child x="this is my awesome string">This is another awesome string<child/><adeena/>
You'd use an XPath expression that looks like this to find the attribute:
//child/#x
and one like this to find the text value under the child tag:
//child
I'm a Java developer, so I don't know what XML libraries you'd use to do this. But you'll need a DOM parser to create a W3C Document class instance for you by reading in the XML file and then using XPath to pluck out the values.
There's a good XPath tutorial from the W3C schools if you need it.
UPDATE:
If you're saying that you already have an XML stream as String, then the answer is to not read it from a file but from the String itself. Java has abstractions called InputStream and Reader that handle streams of bytes and chars, respectively. The source can be a file, a string, etc. Check your C# DOM API to see if it has something similar. You'll pass the string to a parser that will give back a DOM object that you can manipulate.
Since the input is not well-formed XML you won't be able to parse it with any of the built in XML libraries. You'd need a regular expression to extract the well-formed piece. You could probably use one of the more forgiving HTML parsers like HtmlAgilityPack on CodePlex.
This is my solution to match any type of xml using Regex:
C# Better way to detect XML?
The XmlTextReader can parse XML fragments with a special constructor which may help in this situation, but I'm not positive about that.
There's an in-depth article here:
http://geekswithblogs.net/kobush/archive/2006/04/20/75717.aspx

Categories

Resources