I generate a sitemap.xml
XDocument xDoc = new XDocument(
new XDeclaration("1.0", "UTF-8", ""),
new XElement("urlset",
new XAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9"),
new Element (....and so on...)
I get an error
The prefix '' cannot be redefined from '' to 'http://www.sitemaps.org/schemas/sitemap/0.9' within the same start element tag.
Google requires xmlns attribute without any prefix.
Seems that adding default namespace in XDocument is a bit tricky, related question : How to set the default XML namespace for an XDocument
You can try to declare default namespace prefix and use that prefix for all elements within <urlset> like so :
XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
XDocument xDoc = new XDocument(
new XDeclaration("1.0", "UTF-8", ""),
new XElement(ns+"urlset",
new XElement(ns+"otherElement"),
new XElement (....and so on...)
You can solve this problem by using blank namespace like the following:
XNamespace blank = XNamespace.Get(#"http://www.sitemaps.org/schemas/sitemap/0.9");
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement(blank + "urlset",
new XAttribute("xmlns", blank.NamespaceName),
new XElement(blank + "loc", "http://www.abc.eba/"),
new Element (....and so on...)
));
Related
I'm building an xml file using XDocument
XDocument single = new XDocument(
new XDeclaration("1.0", "UTF-8", "true"),
new XElement(_namespace + "vcards",
XElement.Parse(BuildCardEntry(contact))));
Inside BuildCardEntry(contact) I'm adding the namespace to every XElement too.
But my code pruduces this
<vcards xmlns="urn:ietf:params:xml:ns:vcard-3.0">
<vcard xmlns="urn:ietf:params:xml:ns:vcard-3.0">
insted of this
<vcards xmlns="urn:ietf:params:xml:ns:vcard-3.0">
<vcard>
Does somebody know, how to solve this?
Use SaveOptions.OmitDuplicateNamespaces parameter when saving xml.
single.Save(..., SaveOptions.OmitDuplicateNamespaces);
I'm attempting to write a small XML file using c# Linq XDocument.
The final xml file should look like this:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Asset InternalID="SOMEID" LastSaveDate="2016-10-28" LastSaveTime="01:01:33:00" AssetType="New">
<type_metadata>
<FIELD name="filename">SOMEID.MOV</FIELD>
<FIELD name="duration">00:00:00:10</FIELD>
</type_metadata>
</Asset>
</Root>
Here is my code:
XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", null));
doc.Add(new XElement("Root"));
doc.Element("Root").Add(new XElement("Asset"));
doc.Element("Root").Element("Asset").Add(new XAttribute("InternalID", a.InternalID));
doc.Element("Root").Element("Asset").Add(new XAttribute("LastSaveDate", a.lastSaveDate));
doc.Element("Root").Element("Asset").Add(new XAttribute("LastSaveTime", a.lastSaveTime));
doc.Element("Root").Element("Asset").Add(new XAttribute("AssetType", a.AssetType));
doc.Element("Root").Element("Asset").Add(new XElement("type_metadata"));
doc.Element("Root").Element("Asset").Element("type_metadata").Add(new XElement("FIELD"));
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Add(new XAttribute("name","filename"));
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Value = a.filename;
doc.Element("Root").Element("Asset").Element("type_metadata").Add(new XElement("FIELD"));
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Add(new XAttribute("name", "duration"));
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Value = a.duration;
Everything works fine until I try to put in the second "FIELD" element.
What is the proper way to do this? I have done some research, but I cant find a simple answer that is directly relevant to what I'm trying to accomplish.
That's because when you're trying to add second element you're using:
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD")
It will return first element matching the name, which is this case is the previously added "FIELD" element, which already has "name" attribute.
I'd suggest you create the element itself before attaching it to the document. This way you won't have to search for the element over and over again:
XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", null));
var root = new XElement("Root");
var asset = new XElement("Asset");
asset.Add(new XAttribute("InternalID", a.InternalID));
asset.Add(new XAttribute("LastSaveDate", a.lastSaveDate));
asset.Add(new XAttribute("LastSaveTime", a.lastSaveTime));
asset.Add(new XAttribute("AssetType", a.AssetType));
var type_metadata = new XElement("type_metadata");
var field = new XElement("FIELD");
field.Add(new XAttribute("name","filename"));
field.Value = a.filename;
type_metadata.Add(field);
var field2 = new XElement("FIELD");
field2.Add(new XAttribute("name","duration"));
field2.Value = a.duration;
type_metadata.Add(field2);
asset.Add(type_metadata);
root.Add(asset);
doc.Add(root);
Also, you can create the entire document in a single statement:
XDocument doc = new XDocument(
new XDeclaration("1.0", "UTF-8", null),
new XElement("Root",
new XElement("Asset",
new XAttribute("InternalID", a.InternalID),
new XAttribute("LastSaveDate", a.lastSaveDate),
new XAttribute("LastSaveTime", a.lastSaveTime),
new XAttribute("AssetType", a.AssetType),
new Element("type_metadata",
new XElement("FIELD",
new XAttribute("name", "filename"),
a.filename),
new XElement("FIELD",
new XAttribute("name", "duration"),
a.duration)))));
It would be easier if you prepare new FIELD element before adding it to the parent element :
var filename = new XElement("FIELD",
new XAttribute("name","filename"),
a.filename
);
var duration = new XElement("FIELD",
new XAttribute("name","duration"),
a.duration
);
doc.Element("Root").Element("Asset").Element("type_metadata").Add(field);
doc.Element("Root").Element("Asset").Element("type_metadata").Add(duration);
This can be achieved in different ways. I just followed your approach. Since you have multiple FIELD elements, slight modification required in your code. The following code will work as expected.
XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", null));
doc.Add(new XElement("Root"));
doc.Element("Root").Add(new XElement("Asset"));
doc.Element("Root").Element("Asset").Add(new XAttribute("InternalID", "intID"));
doc.Element("Root").Element("Asset").Add(new XAttribute("LastSaveDate", "28.10.2016"));
doc.Element("Root").Element("Asset").Add(new XAttribute("LastSaveTime", "1.48PM"));
doc.Element("Root").Element("Asset").Add(new XAttribute("AssetType", "Laptop"));
doc.Element("Root").Element("Asset").Add(new XElement("type_metadata"));
doc.Element("Root").Element("Asset").Element("type_metadata").Add(new XElement("FIELD"));
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Add(new XAttribute("name", "filename"));
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Value = "a.txr";
doc.Element("Root").Element("Asset").Element("type_metadata").Add(new XElement("FIELD"));
doc.Element("Root").Element("Asset").Element("type_metadata").Elements().Last().Add(new XAttribute("name", "duration"));
doc.Element("Root").Element("Asset").Element("type_metadata").Elements().Last().Value = "00:12:98";
I want to create an XML file with two namespaces for my root element, one default and one named. Following is my code:
var testdoc= new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("Document",
new XAttribute("xmlns", "namespace1"),
new XAttribute(XNamespace.Xmlns + "xsi", "namespace2"),
new XElement("sampleElem", "content")
)
);
This generates the following error:
the prefix for "namespace2" can not be redefined within the same code for starting a new element.
I understand the error, but I do not understand why I get it (as the prefix name is not the same). Anyone know the correct way to get the desired result?
Because in this line new XElement("Document", you have already created an element with a namespace by default. Specifying the attribute you are trying to override it.
Do this
XNamespace ns = "namespace1";
var testdoc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement(ns + "Document",
new XAttribute(XNamespace.Xmlns + "xsi", "namespace2"),
new XElement("sampleElem", "content")
)
);
I am trying to replicate:
<gcf>
<cbxDecOnly Type="Boolean">False</cbxDecOnly>
<cbxFormName Type="String" />
<txtCustomerCellPhonePart2 Type="String">5236</txtCustomerCellPhonePart2>
<txtCustomerCellPhonePart1 Type="String">533</txtCustomerCellPhonePart1>
....
</gcf>
so far I have:
var xdoc = new XDocument(
new XDeclaration("1.0", "utf-8", null),
new XElement("gcf",
new XElement("cbxDecOnly", new XAttribute("Type", "Boolean")),
new XElement("cbxFormName", oGSFE.TextBoxClientName),
new XElement("txtCustomerCellPhonePart2", oGSFE.TextBoxDealSearch),
new XElement("txtCustomerCellPhonePart1 ", oGSFE.DropDownListFIManager)
)
);
what I don't know is how to add a XAttribute and a value at the same time to the XML element <cbxDecOnly Type="Boolean">False</cbxDecOnly>
In the same way you provide the value for your txtCustomerCellPhonePart2 etc nodes - by including the string value as one of the element's params content[]:
var xdoc = new XDocument(
new XDeclaration("1.0", "utf-8", null),
new XElement("gcf",
new XElement("cbxDecOnly", "False", new XAttribute("Type", "Boolean")),
new XElement("cbxFormName", oGSFE.TextBoxClientName),
new XElement("txtCustomerCellPhonePart2", oGSFE.TextBoxDealSearch),
new XElement("txtCustomerCellPhonePart1", oGSFE.DropDownListFIManager)
)
);
Any values of type string provided in content[] will be merged into the element's value, any values of type XAttribute will create attributes and any values of type XElement will become the children.
Using XDocument i can add an element by
new XElement("elementName", "elementText");
and add an attribute by
new XAttribute("attributeName", "attributeValue");
However when i use the following code
XDocument doc =
new XDocument(
new XElement("Address", new XAttribute("name", "sample"))
);
there is no text being added for the element 'Address'
How to add both element and attribute at the same time?
You can pass string as another XElement constructor parameter, and it will be placed as element content:
XDocument doc =
new XDocument(
new XElement("Address",
new XAttribute("name", "sample"),
"elementText"
)
);
Calling doc.ToString() now gives <Address name="sample">elementText</Address>.
Just to let you know: it can be done with XText class too, but I think using plain string is more convenient:
XDocument doc =
new XDocument(
new XElement("Address",
new XAttribute("name", "sample"),
new XText("elementText")
)
);