i am building an XML using XDocument.this is my code
var ns = XNamespace.Get("url");
XDocument requestXMl = new XDocument(
new XElement(ns+"WEB_REQUEST",
new XElement("HTTP_HEADER_INFORMATION",
new XElement("DEFINED_HEADERS",
new XElement("HTTP_DEFINED_REQUEST_HEADER",
new XElement("ItemNameType", "RequestDate"),
new XElement("ItemValue", _currentTime)
),
new XElement("HTTP_DEFINED_REQUEST_HEADER",
new XElement("ItemNameType", "AuthorizationValue"),
new XElement("ItemValue", credentials)
)
)
),
new XElement("COLL",
new XElement("TID", _t),
new XElement("SID", _s)
)
)
);
the output for this code is
<WEB_REQUEST xmlns="url">
<HTTP_HEADER_INFORMATION xmlns="">
<DEFINED_HEADERS>
<HTTP_DEFINED_REQUEST_HEADER>
<ItemNameType>RequestDate</ItemNameType>
<ItemValue>Wed,06 May 2015 18:14:33 GMT</ItemValue>
</HTTP_DEFINED_REQUEST_HEADER>
<HTTP_DEFINED_REQUEST_HEADER>
<ItemNameType>AuthorizationValue</ItemNameType>
<ItemValue>ieuKB5voR3w==</ItemValue>
</HTTP_DEFINED_REQUEST_HEADER>
</DEFINED_HEADERS>
</HTTP_HEADER_INFORMATION>
<COLL xmlns="">
<TID></TID>
<SID></SID>
</COLL>
</WEB_REQUEST>
I don't want the xmlns to appear 3 times as it appears in the output.
I want it to appear only 2 times.
<WEB_REQUEST xmlns="url">
<COLLABORATION xmlns="">
how can i achieve this ?
Specify "url" namespace for the element you don't want to have an empty xmlns.
This clears all the xml namespaces except for the root element:
var ns = XNamespace.Get("url");
XDocument requestXMl = new XDocument(
new XElement(ns+"WEB_REQUEST",
new XElement(ns+"HTTP_HEADER_INFORMATION",
new XElement(ns+"DEFINED_HEADERS",
new XElement(ns+"HTTP_DEFINED_REQUEST_HEADER",
new XElement(ns+"ItemNameType", "RequestDate"),
new XElement(ns+"ItemValue", _currentTime)
),
new XElement(ns+"HTTP_DEFINED_REQUEST_HEADER",
new XElement(ns+"ItemNameType", "AuthorizationValue"),
new XElement(ns+"ItemValue", credentials)
)
)
),
new XElement(ns + "COLL",
new XElement(ns + "TID", _t),
new XElement(ns + "SID", _s)
)
)
);
Related
I am generating a XML file with hundreds of thousands of elements and the runtime of my code is currently over 3 minutes! I have tried both XDocument and XmlDocument to see if either would decrease the runtime; XDocument was better, but only by a small margin. Is there anything else I can try?
Code
string path = Server.MapPath("~/Temp/employee.xml");
XDocument d = new XDocument(new XElement("Employees"));
d.Declaration = new XDeclaration("1.0", "utf-8", "true");
while (reader.Read())
{
d.Root.Add(new XElement("Employee",
new XElement("LastName", reader["lastname"].ToString()),
new XElement("FirstName", reader["firstname"].ToString()),
new XElement("MiddleInitial", reader["middleini"].ToString()),
new XElement("ID", reader["id"].ToString()),
new XElement("Title", reader["title"].ToString()),
new XElement("DOB", reader["title"].ToString()),
new XElement("Category", reader["category"].ToString()),
new XElement("Supervisor", reader["supervisor"].ToString()),
new XElement("CurrentAddress", reader["address1"].ToString()),
new XElement("Address", reader["address2"].ToString()),
new XElement("City", reader["city"].ToString()),
new XElement("State", reader["state"].ToString()),
new XElement("ZipCode", reader["zip"].ToString()),
new XElement("OfficePhone", reader["office_phone"].ToString()),
new XElement("HomePhone", reader["home_phone"].ToString()),
new XElement("Email", reader["email_address"].ToString()),
new XElement("DateHired", reader["chem_employment_date"].ToString()),
new XElement("DateTerminated", reader["emp_terminate_date"].ToString()),
new XElement("StatusCode", reader["status_code"].ToString()),
new XElement("Room", reader["room"].ToString()),
new XElement("IsPrivate", reader["isprivate"].ToString()),
new XElement("Floor", reader["floor"].ToString()),
new XElement("Wing", reader["wing"].ToString()),
new XElement("InRoster", reader["isroster"].ToString()),
new XElement("RosterCategory", reader["roster_category"].ToString()),
new XElement("LastModified", reader["lastmodified"].ToString()),
new XElement("ShowReport", reader["isbudget"].ToString()),
new XElement("ModifiedBy", reader["lastmodifiedby"].ToString())
));
d.Save(path);
}
Try using the xmlwriter class
https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmlwriter?view=net-5.0
C# export of large datatbase to XML
XmlWriter uses less memory than XmlDocument, but you will have to write the entire document from scratch each time.
I'm using [Produces("application/xml")] data annotation to return my response in XML but unfortunately it do not return any thing. When I remove [Produces] data annotation it returns me data in JSON format. I've also added AddXmlSerializerFormatters() formatter.
Here is my controller action
[HttpGet("Generate")]
[Produces("application/xml")]
public XDocument Get()
{
XDocument sitemap = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"),
new XElement("urlset", XNamespace.Get("http://www.sitemaps.org/schemas/sitemap/0.9"),
from item in business
select CreateItemElement(item)
)
);
return Ok(sitemap.ToString());
}
Here is my ConfigureService method in startup class
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddXmlSerializerFormatters()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddDbContext<ListingDbContext>
(options => options.UseSqlServer(Configuration.GetConnectionString("App4Rental_Website_DB")));
services.AddTransient<IRentalRepository, RentalRepository>();
services.AddTransient<IScrapingRepository, ScrapingRepository>();
}
Its working fine JSON result but not working for XML. I'm unable to understand problem.
For XDocument, it should not be serialized to xml format.
In general, we return Object like Product with xml formatter. You could try return Product to test [Produces("application/xml")].
If you want to return XDocument, you may consider return string directly like
public string Get()
{
XDocument srcTree = new XDocument(
new XComment("This is a comment"),
new XElement("Root",
new XElement("Child1", "data1"),
new XElement("Child2", "data2"),
new XElement("Child3", "data3"),
new XElement("Child2", "data4"),
new XElement("Info5", "info5"),
new XElement("Info6", "info6"),
new XElement("Info7", "info7"),
new XElement("Info8", "info8")
)
);
XDocument doc = new XDocument(
new XComment("This is a comment"),
new XElement("Root",
from el in srcTree.Element("Root").Elements()
where ((string)el).StartsWith("data")
select el
)
);
return doc.ToString();
}
Update:
The expected result is caused by the wrong XDocument creation. Try something like below:
XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
XDocument sitemap = new XDocument(new XDeclaration("1.0", "UTF-8", "yes"),
new XElement(ns + "urlset",
new XElement(ns + "url",
new XElement(ns + "loc", "http://app4rental.com/business/100/r.s.-enterprises"),
new XElement(ns + "lastmod", "2019-08-01"),
new XElement(ns + "changefreq", "weekly"),
new XElement(ns + "priority", "0.8")
)));
return sitemap.ToString();
I've written a method to serialize a list (containing class objects) into an xml string, but with so many nests I can't figure out how to format my code to make it the most readable. Here's the xml example:
<Text>
<Info name="example" language="en-US">example</Info>
<Info name="example" language="en-GB">example</Info>
</Text>
And here's the (most likely) terribly formatted code:
XDocument xdoc = new XDocument
(
new XElement
("Text",
Infos.Select(item =>
new XElement
("Info",
new XAttribute("name", item.Name),
new XAttribute("language", item.Language),
item.Value)
)
)
);
return xdoc.ToString();
This is a fairly short example, but it may grow in the future and as such, I'd like to make my code the most readable - how do I do that here?
I like this format
//Option 1
XDocument xdoc1 = new XDocument();
xdoc1.Add(new XElement("Text",
Infos.Select(item => new XElement("Info",
new XAttribute("name", item.Name),
new XAttribute("language", item.Language),
item.Value
)
)
));
//Option 2
XDocument xdoc2 = new XDocument();
xdoc2.Add(new XElement("Text", new object[] {
Infos.Select(item => new XElement("Info", new object[] {
new XAttribute("name", item.Name),
new XAttribute("language", item.Language),
item.Value
}))
}));
I am new to XML and tried the following but I'm getting an exception. Can someone help me?
The exception is This operation would create an incorrectly structured document
My code:
string strPath = Server.MapPath("sample.xml");
XDocument doc;
if (!System.IO.File.Exists(strPath))
{
doc = new XDocument(
new XElement("Employees",
new XElement("Employee",
new XAttribute("id", 1),
new XElement("EmpName", "XYZ"))),
new XElement("Departments",
new XElement("Department",
new XAttribute("id", 1),
new XElement("DeptName", "CS"))));
doc.Save(strPath);
}
Xml document must have only one root element. But you are trying to add both Departments and Employees nodes at root level. Add some root node to fix this:
doc = new XDocument(
new XElement("RootName",
new XElement("Employees",
new XElement("Employee",
new XAttribute("id", 1),
new XElement("EmpName", "XYZ"))),
new XElement("Departments",
new XElement("Department",
new XAttribute("id", 1),
new XElement("DeptName", "CS"))))
);
You need to add root element.
doc = new XDocument(new XElement("Document"));
doc.Root.Add(
new XElement("Employees",
new XElement("Employee",
new XAttribute("id", 1),
new XElement("EmpName", "XYZ")),
new XElement("Departments",
new XElement("Department",
new XAttribute("id", 1),
new XElement("DeptName", "CS")))));
In my case I was trying to add more than one XElement to xDocument which throw this exception. Please see below for my correct code which solved my issue
string distributorInfo = string.Empty;
XDocument distributors = new XDocument();
XElement rootElement = new XElement("Distributors");
XElement distributor = null;
XAttribute id = null;
distributor = new XElement("Distributor");
id = new XAttribute("Id", "12345678");
distributor.Add(id);
rootElement.Add(distributor);
distributor = new XElement("Distributor");
id = new XAttribute("Id", "22222222");
distributor.Add(id);
rootElement.Add(distributor);
distributors.Add(rootElement);
distributorInfo = distributors.ToString();
Please see below for what I get in distributorInfo
<Distributors>
<Distributor Id="12345678" />
<Distributor Id="22222222" />
</Distributors>
I'm trying to generate an XML document like the one below. I tried several solution but when I add the namespace, I have the namespace almost everywhere
like
<FieldB xlmns="">BBBBB</FieldB>
Do you have an idea how to get this ?
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<value attributeA="A" attributeB="B" xmlns:XXX="http://MyURLA" xmlns="http://MyURLB">
<FieldA>AAAAA</FieldA>
<FieldB>BBBBB</FieldB>
<FieldB>BBBBB</FieldB>
<status attributeC="C">
<FieldC>ValueFieldC</FieldC>
</status>
<LastUpdate date="2011-02-11T10:00:56.350" login="testing"/>
<XXX:Infos>
<XXX:Info>
<XXX:InfoA>false</XXX:InfoA>
<XXX:InfoB>false</XXX:InfoB>
</XXX:Info>
</XXX:Infos>
</value>
You could use a XNamespace:
public class Program
{
static void Main()
{
XNamespace nsA = "http://MyURLA";
XNamespace nsB = "http://MyURLB";
var doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement(
nsB + "value",
new XAttribute(XNamespace.Xmlns + "XXXX", nsA),
new XAttribute("attributeA", "A"),
new XAttribute("attributeB", "B"),
new XElement("FieldA", "AAAA"),
new XElement("FieldA", "BBBB"),
new XElement("FieldC", "CCCC"),
new XElement(
"status",
new XAttribute("attributeC", "C"),
new XElement("FieldC", "ValueFieldC")
),
new XElement(
"LastUpdate",
new XAttribute("date", DateTime.Now),
new XAttribute("login", "testing")
),
new XElement(
nsA + "Infos",
new XElement(nsA + "InfoA", false),
new XElement(nsA + "InfoB", false)
)
)
);
Console.WriteLine(doc.ToString());
}
}
I suspect the problem is that you're not putting FieldA, FieldB etc in the right namespace - you don't want to have an explicit namespace declaration in the XML, but the XML you've shown will actually have them in the namespace with URL http://MyURLB, due to the way defaults are inherited.
I suspect if you just use:
XNamespace nsB = "http://MyURLB";
var doc = ... {
new XElement(nsB + "value",
...
new XElement(nsB + "FieldA", "AAAA");
new XElement(nsB + "FieldB", "BBBB");
new XElement(nsB + "FieldC", "CCCC");
...
)
};
then it'll be fine. The FieldA (etc) elements won't have an explicit namespace reference, because they're in the same namespace as their parent element.