How do I rename xmlns="" with WriteStartElement? - c#

I'm attempting to make an XML that's going to be parsed by an XNA content reader. I'm using XMLWriter, and the format is supposed to be:
<XNAContent>
<Assest Type="namespace">
<Element>"Value"</Element>
</Asset>
<XNAContent>
But when I use WriteStartElement to declare a namespace, I get:
<XNAContent>
<Assest xmlns="namespace">
<Element>"Value"</Element>
</Asset>
<XNAContent>
It's important that I have Asset Type= instead of Asset xmlns= because of what the pipeline expects, but I can't find an overload that let's me rename that default tag.
Is there a way for XMLWriter to let me put my own tag there as described? Thanks, all.

You are confusing XML attributes with namespaces, xmlns is a 'special' attribute that defines the namespace for an XML element and its children. Whereas your Type is simple an attribute. To write an attribute value use the WriteAttributeString method.
For example:
writer.WriteStartElement("Asset");
writer.WriteAttributeString("Type", "namespace");
writer.WriteEndElement();
will result in
<Asset Type="namespace">
</Asset>

Related

XmlDocument InnerXml adds redundant namespace attributes

Using C# XmlDocument object to edit an xml document which includes namespace declarations:
<tdl xmlns="http://www.nema.org/1997/C1219TDLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tbd="http://www.example.com/tables/tbd/"
xmlns:xxx="http://www.example.com/tables/xxx/"
xsi:schemaLocation="http://www.nema.org/1997/C1219TDLSchema C1219TDL.xsd"
version="1.0" ></tdl>
I then add nodes to the document (setting InnerXml) that have tags and attributes that reference these namespaces.
I have 2 problems:
If the created tag is in the default namespace, it is written with an empty namespace attribute
<packedRecord name="ITEM_RCD" xmlns="">
If it uses a defined namespace, then it includes the namespace attribute:
<tbd:text xmlns:tbd="http://www.example.com/tables/tbd/">Ph</tbd:text>
Since these name spaces are defined in the document, my understanding (based on MSDN - XmlDocument.InnerXml) was that InnerXml would strip them out.
How do I get them to be stripped out?

Add attribute without name and value?

Whether XML element attribute name can be empty:
<?xml version="1.0" encoding="utf-8"?>
<test>
<tables>
<gg qqq="">
<ss ""=""/>
<mm ""=""/>
</gg>
</tables>
</test>
I am getting an exception I cant to load this. Is this possible?
No, this will produce invalid XML. Attribute must have both name and value. How do you image opposite?
No this can not be done.
XML has empty element concept[If you are trying to implement that].
In that whole element is kept empty and said to be null as follow>>
<abc></abc>
<DefaultTaxPrice></DefaultTaxPrice>
Short answer, no. If you want to add value but not know what is the name of the value in XML, insert in into the body instead.
<ss>value</ss>
This way, your ss will be treated as a value

Using XSD.exe for c# code gen, ignores empty nodes in XML?

Maybe I'm not doing this correctly. But I'm using MusicXML, along with XSD.exe to generate the C# classes against the DTD.
According to the documentation, along with a sample xml file, the <NOTE> element contains an empty <CHORD> element, if the <NOTE> is a part of a <CHORD>. The code generated looks like this:
[System.Xml.Serialization.XmlElementAttribute("chord", typeof(empty))]
When I deserialize the XML into a c# object, it works great, but the <CHORD> seems to disappear. Does .NET just ignore the CHORD element in this sample XML?
<note>
<chord/>
<pitch>
<step>E</step>
<alter>-1</alter>
<octave>4</octave>
</pitch>
<duration>1</duration>
</note>
Thanks!
Do you mean the chord element dissapears when you serialize to XML, as null elements don't serialize by default
If you want to render it as an empty element like
<chord />
you can set use the isnullable property
XML Serialization and null value - C#
As linked in another question you might want to have a look at this article about the representation of null in XML Schema files:
http://www.ibm.com/developerworks/xml/library/ws-tip-null/index.html

XML namespace alias agnostic .NET XML reader/parsing

How do I read/parse an XML document where the XML namespace alias is unknown?
The structure and namespaces of the XML document are known, but the alias is not. E.g.
<?xml version="1.0" encoding="utf-8"?>
<Order xmlns:aa="urn:namespace1"
xmlns:bb="urn:namespace2">
<aa:Quantity>1</aa:Quantity>
<bb:Price>9.98</bb:Price>
</Order>
Or
<?xml version="1.0" encoding="utf-8"?>
<Order xmlns:cc="urn:namespace1"
xmlns:dd="urn:namespace2">
<cc:Quantity>1</cc:Quantity>
<dd:Price>9.98</dd:Price>
</Order>
Update: I don't know the XML namespace aliases up front. They can be whatever.
I need to supply the XmlNamespaceManager with a list of namespaces and alias with the AddNameSpace method like so:
XPathDocument xDoc = new XPathDocument(“Path to my file”);
XPathNavigator xNav = xDoc.CreateNavigator();
XmlNamespaceManager xmlns = new XmlNamespaceManager(xNav.NameTable);
xmlns.AddNamespace("aa", "urn:namespace1");
xmlns.AddNamespace("bb", "urn:namespace2");
But this is not XML namespace agnostics. My second document uses cc and dd as alias for the same namespace.
The code you have provided is namespace agnostic in the sense that the namespace prefixes used in the source XML does not matter. Given the namespace definitions in your question you have to use the prefixes defined by you in the XPATH, e.g. you have to use aa and bb.
var quantity = xNav.SelectSingleNode("/Order/aa:Quantity", xmlns);
However, this code will still successfully select from the XML where prefixes cc and dd are used as long as the namespaces urn:namespace1 and urn:namespace2 are correctly used.
To be able to include namespace prefixes in the XPATH you have to use the overloads that accepts an IXmlNamespaceResolver.
To reiterate: When you define a namespace using the following code
xmlns.AddNamespace("aa", "urn:namespace1");
You state that in your code (e.g. in the XPATH you intend to use) you will be using namespace prefix aa for namespace urn:namespace1.
In the XML you want to parse you assign namespaces using an attribute:
xmlns:cc="urn:namespace1"
It is important that the string urn:namespace1 matches both places to use that particular namespace. The prefixes are local to your code and the XML file respectively and they do not have to match.
The namespace aliases used in the document don't matter - they are just the aliases that are used in the document and can be whatever the author of that document wanted to use when authoring that document (they can even change mid-document).
To access this document in a alias-agnostic way just provide whatever alias you want to use to the XmlNamespaceManager and then use that alias to access the document, for example
XmlNamespaceManager xmlns = new XmlNamespaceManager(xNav.NameTable);
xmlns.AddNamespace("foo", "urn:namespace1");
xmlns.AddNamespace("bar", "urn:namespace2");
These aliases don't need to match the ones used in the document - this then allows you to use XPath expressions using the foo and bar aliases for those namespaces to navigate the document regardless of the aliases used in the document itself (as long as you supply that instance of XmlNamespaceManager).

Why doesn't XDocument.Parse() parse my XML properly?

I am trying to use XDocument.Parse(string s) to parse some XML that is being returned from a REST based API. After the XML is parsed, it creates a new XDocument, but the document doesn't contain the properly parsed XML nodes. The name of the first node is the correct node name, but the value is the the concatenation of all the text from the XML, regardless of which Element is belongs to. Can anybody help me figure out what is going on?
XML
<sci_reply version="1.0">
<send_message>
<device id="00000000-00000000-00000000-00000000">
<error id="303">
<desc>Invalid target. Device not found.</desc>
</error>
</device>
<error>Invalid SCI request. No valid targets found.</error>
</send_message>
</sci_reply>
Debug View of XDocument Object
That's the expected behavior. The Value of a an XML element is concatenation of values of all its children. If you want to actually access the XML, read something about LINQ to XML or classes in the System.Xml.Linq namespace.
Thats just the debugger being nice.
The root is being displayed with all of its children.

Categories