In C#, assume that I have an XElement (say myXElement) containing some XML structure. By calling
myXElement.Save("/path/to/myOutput.xml");
the XML is written to a text file. However, I would like this textfile to include a reference to a (local) xsd-file (an XML schema). That is, I would like the output to look something like this...
<?xml version="1.0" encoding="utf-8" ?>
<MyElement
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="MySchema.xsd">
...
How can I do this?
On the root element, just add an attribute:
Example 1:
XmlDocument d = new XmlDocument();
XmlElement e = d.CreateElement("MyElement");
XmlAttribute a = d.CreateAttribute("xsi", "noNamespaceSchemaLocation", "http://www.w3.org/2001/XMLSchema-instance");
a.Value = "MySchema.xsd";
d.AppendChild(e);
e.Attributes.Append(a);
Example 2:
XDocument d = new XDocument();
XElement e = new XElement("MyElement");
XAttribute a = new XAttribute(XName.Get("noNamespaceSchemaLocation", "http://www.w3.org/2001/XMLSchema-instance"), "MySchema.xsd");
d.Add(e);
e.Add(a);
You should use XDocument instead of XElement as this contains methods for getting and setting the XML declaratuion etc
http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx
Related
I have the code in an .xml file, I would like to assign to the field the value of the attribute from the .xml file.
.csharp
private static string camera_model_c1_set = xml_read_set_cip_c1.Descendants("root").ElementAt("camera_model_c1_set").Att
.csharp
Parameter name: value '
XDocument name_of_file_xml = new XDocument(
new XComment("document"),
new XElement("root",
new XElement("name", new XAttribute ("name2", myvalue ))
)
);
.xml
<?xml version="1.0" encoding="utf-8"?>
<!--document-->
<root>
<name name2="myvalue" />
</root>
and I want to get this "myvalue" to .cs code to:
static string new_my_var = ... (?)
I have
XDocument xml_doc = XDocument.Load(path);
I care about using XDocument in this code. (instead of XmlDocument)
Try this for reading the attribute from an xml file :
XmlDocument doc = new XmlDocument();
doc.Load("Path/document.xml");
XmlNodeList elem = doc.GetElementsByTagName("name");
static string new_my_var = elem.Attributes["name2"].Value;
I have got problems to update a XML Document.
<?xml version="1.0" encoding="utf-16"?>
<test>
<settings server="1" />
</test>
For example I want to update the "1".
I tried like this:
XmlDocument doc = new XmlDocument();
doc.Load(path);
doc.SelectSingleNode("test/settings/server").InnerText = "2"
doc.Save(path);
I think this should be easy to solve, but I am really a blockhead.
UPDATE:
I have tried your solutions and they work with the given example.
Thank you to all of you!
But in the given XML, there is a weird structure, I got problems with:
<?xml version="1.0" encoding="utf-16"?>
<test>
<settings server="1" />
<settings config="999" />
</test>
With this structure none of your solutions work and i always get a "System.NullReferenceException" if I try to change the '999' of config.
I only can access the '1' of server.
Sorry, I didn't expected this and tried to keep the example as easy as possible.
You can do this with
var path = #"C:\users\bassie\desktop\test.xml";
var doc = new XmlDocument();
doc.Load(path);
var settings = doc.SelectSingleNode("test/settings");
settings.Attributes["server"].Value = "2";
doc.Save(path);
InnerText would be used if you wanted to update settings to read something like:
<settings server="1"> 2 </settings>
Where you are trying to update an attribute of the settings element.
Regarding your update, you can replace doc.SelectSingleNode with doc.SelectNodes like so:
var settings = doc.SelectNodes("test/settings");
This will select all the available settings elements under test.
Then when setting the attribute you just provide the index of the element you want to target, e.g.:
settings[0].Attributes["server"].Value = "2";
to update the value of server, or
settings[1].Attributes["config"].Value = "000";
to update the value of config.
However
I think your best best here would be to use System.Xml.Linq, so that you can select the correct settings element by attribute name:
var document = XDocument.Load(path);
var attributeName = "server";
var element = document.Descendants("settings")
.FirstOrDefault(el => el.Attribute(attributeName) != null);
That code gets all settings elements (Descendants) in the document, and then selects the first one where the attributeName ("server" in this case) is not null.
This of course relies on the fact that each attribute only appear once (i.e. you can't have multiple settings elements with the "server" attribute), as it uses the FirstOrDefault selector meaning it will only return 1 element.
Hope this helps
server is an attribute
var doc = new XmlDocument();
doc.Load(path);
doc.SelectSingleNode("test/settings").Attributes["server"].Value = "2"
doc.Save(path);
Try this:
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode root = doc.DocumentElement;
XmlNode myNode = root.SelectSingleNode("test/settings");
myNode.Attributes["server"].Value = "2";
doc.Save(path);
Or LINQ to XML
var document = XDocument.Load(path);
document.Descendants("settings").First().Attribute("server").Value = "2";
document.Save(path);
How to read namespaces from code? I want to get xmlns:es, xmlns:un, xmlns:xn attribute values, but I get null attributes, How do I read it?
I try like this:
XNamespace xmlns = xdoc.Root.Attribute("xmlns").Value;
XNamespace ES = xdoc.Root.Attribute(xmlns + "es").Value;
XML:
<?xml version="1.0" encoding="UTF-8"?>
<xmlFile xmlns:es="my.xsd"
xmlns="not_my.xsd">
...
</xmlFile>
XNamespace defns = xdoc.Root.GetDefaultNamespace();
XNamespace es = xdoc.Root.GetNamespaceOfPrefix("es");
I'm trying to parse the following XML:
<?xml version="1.0" encoding="utf-8"?>
<A2AAnf:MPPPPPP xsi:schemaLocation="urn:A2AAnf:xsd:$MPPPPPP.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:A2AAnf="urn:A2AAnf:xsd:$MPPPPPP">
<A2AAnf:Num>0</A2AAnf:Num>
<A2AAnf:FIT xmlns="urn:iso:std:iso:20022:xsd:003.001">
<Hdr>
<Inf>
<Mtd>TEST</Mtd>
</Inf>
</Hdr>
</A2AAnf:FIT>
I want to access the <Mtd> tag.
XMLQuire shows the path to be /A2AAnf:MPPPPPP/A2AAnf:FIT/dft:Hdr/dft:Inf/dft:Mtd, but when I'm trying to parse it using the following code:
XmlDocument xmldocument = new XmlDocument();
var xmlNameSpaceManager = new XmlNamespaceManager(xmldocument.NameTable);
xmlNameSpaceManager.AddNamespace("A2AAnf", "urn:A2AAnf:xsd:$MPPPPPP");
try
{
xmldocument.LoadXml(m_XML);
var node = xmldocument.SelectSingleNode("/A2AAnf:MPPPPPP/A2AAnf:FIT/dft:Hdr/dft:Inf/dft:Mtd", xmlNameSpaceManager);
}
I receive the following error:
namespace prefix 'dft' is not defined
And since I can't find "dft" in my XML, I also tried to remove the "dft" prefix and search for the same string without "dft". This time, nothing was returned.
What am I missing?
You have to add dft to your XmlNamespaceManager:
var xmlNameSpaceManager = new XmlNamespaceManager(xmldocument.NameTable);
xmlNameSpaceManager.AddNamespace("A2AAnf", "urn:A2AAnf:xsd:$MPPPPPP");
xmlNameSpaceManager.AddNamespace("dft", "urn:iso:std:iso:20022:xsd:003.001");
The prefixes you use in your XPath query have nothing to do with the prefixes used in the XML document. They are instead the prefixes you define in your XmlNamespaceManager.
I work with three kinds of XML files :
Type A:
<?xml version="1.0" encoding="UTF-8"?>
<nfeProc versao="2.00" xmlns="http://www.portalfiscal.inf.br/nfe">
</nfeProc>
Tyepe B:
<?xml version="1.0" encoding="UTF-8"?>
<cancCTe xmlns="http://www.portalfiscal.inf.br/cte" versao="1.04">
</cancCTe>
Type C:]
<?xml version="1.0" encoding="UTF-8"?>
<cteProc xmlns="http://www.portalfiscal.inf.br/cte" versao="1.04">
</cteProc>
I have try with this code to read the first node :
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"C:\crruopto\135120068964590_v01.04-procCTe.xml");
XmlNodeList ml = xmlDoc.GetElementsByTagName("*");
XmlElement root = xmlDoc.DocumentElement;
exti = root.ToString();
but dont return anything i want to read the first node , need to know if the file is nfeProc ,canCTE or cteProc
The second question is how i get the value from "value" in the same tag???
Thanks
From this post:
//Root node is the DocumentElement property of XmlDocument
XmlElement root = xmlDoc.DocumentElement
//If you only have the node, you can get the root node by
XmlElement root = xmlNode.OwnerDocument.DocumentElement
I would suggest using XPath. Here's an example where I read in the XML content from a locally stored string and select whatever the first node under the root is:
XmlDocument doc = new XmlDocument();
doc.Load(new StringReader(xml));
XmlNode node = doc.SelectSingleNode("(/*)");
If you aren't required to use the XmlDocument stuff, then Linq is your friend.
XDocument doc = XDocument.Load(#"C:\crruopto\135120068964590_v01.04-procCTe.xml");
XElement first = doc.GetDescendants().FirstOrDefault();
if(first != null)
{
//first.Name will be either nfeProc, canCTE or cteProc.
}
Working with Linq to XML is the newest and most powerful way of working with XML in .NET and offers you a lot more power and flexibility than things like XmlDocument and XmlNode.
Getting the root node is very simple:
XDocument doc = XDocument.Load(#"C:\crruopto\135120068964590_v01.04-procCTe.xml");
Console.WriteLine(doc.Root.Name.ToString());
Once you have constructed an XDocument you don't need to use any LINQ querying or special checking. You simply pull the Root property from the XDocument.
Thanks i have solved this way the first part
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(nomear);
XmlNodeList ml = xmlDoc.GetElementsByTagName("*");
XmlNode primer = xmlDoc.DocumentElement;
exti = primer.Name;
First, to be clear, you're asking about the root element, not the root node.
You can use an XmlReader to avoid having to load large documents completely into memory. See my answer to a how to find the root element at https://stackoverflow.com/a/60642354/1307074.
Second, once the reader is referencing the element, you can use the reader's Name property to get the qualified tag name of the element. You can get the value as a string using the Value property.