This question already has answers here:
Adding a prefix to an xml node
(2 answers)
Rewrite XMLDocument to use namespace prefix
(3 answers)
Closed 2 years ago.
I need to create XML like below. Because of retardation of target system. I need to have prefixes in front of all nodes. All nodes need to have "ns0" prefix present.
<?xml version="1.0" encoding="utf-8"?>
<ns0:RootElement xmlns:ns0="http://top-secret">
<ns0:MainMessage>
<ns0:Date>1</ns0:Date>
<ns0:Field1>2</ns0:Field1>
<ns0:Field2>3</ns0:Field2>
</ns0:MainMessage>
</ns0:RootElement>
There is no schema. I need to add nodes depending on user input. This is sample of the code that add nodes to "ns0:MainMessage" element:
XmlDocument xml = new XmlDocument();
xml.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><ns0:RootElement xmlns:ns0=\"http://top-secret\"><ns0:MainMessage></ns0:MainMessage></ns0:RootElement>");
XmlElement mainMessageElement = xml.DocumentElement["ns0:MainMessage"];
XmlElement newElement = mainMessageElement.OwnerDocument.CreateElement("Date");
newElement.Prefix = "ns0";
newElement.InnerText = "thisIsTest;
mainMessageElement.AppendChild(newElement);
This produces output like this:
<?xml version="1.0" encoding="utf-8"?>
<ns0:RootElement xmlns:ns0="http://top-secret">
<ns0:MainMessage>
<Date>thisIsTest</Date>
</ns0:MainMessage>
</ns0:RootElement>
While I need output where "Date" element is prefixed with "ns0" like "ns0:Date". Like so:
<?xml version="1.0" encoding="utf-8"?>
<ns0:RootElement xmlns:ns0="http://top-secret">
<ns0:MainMessage>
<ns0:Date>thisIsTest</ns0:Date>
</ns0:MainMessage>
</ns0:RootElement>
How to force this Date element to have ns0 prefix?
You need to actually qualify the element into the correct namespace:
var newElement = mainMessageElement.OwnerDocument.CreateElement(
"Date", "http://top-secret");
newElement.Prefix = "ns0";
Note, however, that it may be easier to do all of this with the XDocument API.
Related
This question already has answers here:
Can a XML element contain text and child elements at the same time?
(2 answers)
Closed 7 months ago.
I have a XML document looking like this:
<?xml version="1.0" encoding="utf-8"?>
<root>
<node>some Text
<subnode>other text</subnode>
</node>
</root>
Now I want to get the content of node without the subnode- in my example only "some Text".
I tried XmlNode.InnerText (gives me the whole text with subnodes) and XmlNode.Value (gives me null)
Now I wonder, if this is valid XML at all and if yes how to get it in C#?
Yes, it is indeed a valid XML. You can use Linq to XML to retrieve the text. Some Text is notated as TextNode you can verify it with NodeType property.
using System.Xml.Linq;
var xmlText = #"<?xml version=""1.0"" encoding=""utf - 8""?>
<root>
<node> some Text
<subnode> other text </subnode>
</node>
</root>";
var xml = XElement.Parse(xmlText);
var textNode = (xml.FirstNode as XElement).FirstNode;
Console.WriteLine(textNode.ToString());
Fiddle
I have a log file in xml format like
<log> // skip this node
<?xml version="1.0" encoding="UTF-8"?>
<qbean logger="main-logger">
</qbean>
</log>
<log> // go to this node
</log>
Now ReadToNextSibling("log") throw an exception an I need to skip content of first "log" tag and move to next "log" tag without throwing exception.
Is there a way?
Hint:
Your XML is invalid since the <?xml version="1.0" encoding="UTF-8"?> has to be before the root element. You can search for it and remove it if that fixes your problem. You can use yourXml.Repalce("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "")
You have to create a root element for your XML to be valid for parsing.
Then, you can use the XmlDocument class to parse the XML data that you have and skip anything you want. You would need something like this:
var document = new XmlDocument();
document.LoadXml(yourXml);
document.DocumentElement.ChildNodes[1]
I have the following XML structure:
<?xml version="1.0" encoding="utf-16"?>
<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>
<StoreResponse xmlns="http://www.some-site.com">
<StoreResult>
<Message />
<Code>OK</Code>
</StoreResult>
</StoreResponse>
</soap:Body>
</soap:Envelope>
I need to get the InnerText from Codeout of this document and I need help with the appropriate XPATH statement.
I'm really confused by XML namespaces. While working on a previous namespace problem in another XML document, I learned, that even if there's nothing in front of Code (e.g. ns:Code), it is still part of a namespace defined by the xmlns attribute in its parent node. Now, there are multiple xmlns nodes defined in parents of Code. What is the namespace that I need to specify in an XPATH statement? Is there such a thing as a "primary namespace"? Do childnodes inherit the (primary) namespace of it's parents?
The namespace of the <Code> element is http://www.some-site.com. xmlsn:xxx means that names prefixed by xxx: (like soap:Body) have that namespace. xmlns by itself means that this is the default namespace for names without any prefix.
An example of using an XDocument (Linq) approach:
XNamespace ns = "http://www.some-site.com";
var document = XDocument.Parse("your-xml-string");
var elements = document.Descendants( ns + "StoreResult" )
Descendant elements will inherit the last immediate namespace. In your example you will need to create two namespaces one for the soap envelope and a second for "some-site".
Here's an option I found in this question: Weirdness with XDocument, XPath and namespaces
var xml = "<your xml>";
var doc = XDocument.Parse(xml); // Could use .Load() here too
var code = doc.XPathSelectElement("//*[local-name()='Code']");
This question already has answers here:
Reading a value from root node XML
(4 answers)
Closed 9 years ago.
Need to write C# how to read configuration's version value = 1.0.1.2 in xml? I want to get this value then assign it to a string variable. Your example code would be much apprecaited. Thanks!
<?xml version="1.0" encoding="utf-8" ?>
<Configuration version="1.0.1.2" createDate="2013-07-04T10:00:00">
<config>
.
.
.
.
</config>
</Configuration>
You can use LINQ to XML (this will load whole xml file into memory):
XDocument xdoc = XDocument.Load(path_to_xml);
var version = (string)xdoc.Root.Attribute("version");
Or use XmlReader to avoid loading file into memory:
using(XmlReader reader = XmlReader.Create(path_to_xml))
{
reader.MoveToContent();
var version = reader.GetAttribute("version")
}
I'm trying to access UPS tracking info and, as per their example, I need to build a request like so:
<?xml version="1.0" ?>
<AccessRequest xml:lang='en-US'>
<AccessLicenseNumber>YOURACCESSLICENSENUMBER</AccessLicenseNumber>
<UserId>YOURUSERID</UserId>
<Password>YOURPASSWORD</Password>
</AccessRequest>
<?xml version="1.0" ?>
<TrackRequest>
<Request>
<TransactionReference>
<CustomerContext>guidlikesubstance</CustomerContext>
</TransactionReference>
<RequestAction>Track</RequestAction>
</Request>
<TrackingNumber>1Z9999999999999999</TrackingNumber>
</TrackRequest>
I'm having a problem creating this with 1 XmlDocument in C#. When I try to add the second:
<?xml version="1.0" ?> or the <TrackRequest>
it throws an error:
System.InvalidOperationException: This
document already has a
'DocumentElement' node.
I'm guessing this is because a standard XmlDocument would only have 1 root node. Any ideas?
Heres my code so far:
XmlDocument xmlDoc = new XmlDocument();
XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
XmlElement rootNode = xmlDoc.CreateElement("AccessRequest");
rootNode.SetAttribute("xml:lang", "en-US");
xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement);
xmlDoc.AppendChild(rootNode);
XmlElement licenseNode = xmlDoc.CreateElement("AccessLicenseNumber");
XmlElement userIDNode = xmlDoc.CreateElement("UserId");
XmlElement passwordNode = xmlDoc.CreateElement("Password");
XmlText licenseText = xmlDoc.CreateTextNode("mylicense");
XmlText userIDText = xmlDoc.CreateTextNode("myusername");
XmlText passwordText = xmlDoc.CreateTextNode("mypassword");
rootNode.AppendChild(licenseNode);
rootNode.AppendChild(userIDNode);
rootNode.AppendChild(passwordNode);
licenseNode.AppendChild(licenseText);
userIDNode.AppendChild(userIDText);
passwordNode.AppendChild(passwordText);
XmlElement rootNode2 = xmlDoc.CreateElement("TrackRequest");
xmlDoc.AppendChild(rootNode2);
An XML document can only ever have one root node. Otherwise it's not well formed. You will need to create 2 xml documents and join them together if you need to send both at once.
Its throwing an exception because you are trying to create invalid xml. XmlDocument will only generate well formed xml.
You could do it using an XMLWriter and setting XmlWriterSettings.ConformanceLevel to Fragment or you could create two XmlDocuments and write them out into the same stream.
Build two separate XML documents and concatenate their string representation.
It looks like your node structure always be the same. (I don't see any conditional logic.) If the structure is constant you could define an XML template string. Load that string into an XML Document & do a SelectNode to populate individual nodes.
That may be simpler/cleaner than programatically creating the root, elements & nodes.