remove namespace from childnode created element - c#

In order to manipulate the dlls thats used inside of my VS project I have to update the reference that the dll is pointed to. I do this via modifying the XML of the csproh (yes this works).
However, this time around I want to add the a SpecificVersion reference so <SpecificVersion xmlns="">False</SpecificVersion> however you cannot build using microsoft build engine when you have a custom xml namespace beneath the Reference element. How do you remove the xmlns="" inside of the SpecificVersion node?
<SpecificVersion xmlns="">False</SpecificVersion>
XmlElement SpecificVersionElement = refNode.OwnerDocument.CreateElement("SpecificVersion");
SpecificVersionElement.InnerText = "False";
refNode.AppendChild(SpecificVersionElement);

Remarkable, like usual 30 seconds after I post something I figure it out. And in this case it makes no sense. By specifying a namespace, the createelement effectively removes the namespace.
XmlElement SpecificVersionElement = refNode.OwnerDocument.CreateElement("SpecificVersion","http://schemas.microsoft.com/developer/msbuild/2003");
SpecificVersionElement.InnerText = "False";
refNode.AppendChild(SpecificVersionElement);
Of course this is probably hidden somewhere deep in a MSDN article

Related

How to modify Solution/Project object?

I have defined attribute MyAttribute : Attribute that is supposed to be used exactly once within a class (only one constructor per class may have it and it can appear only once on ctor’s attribute list).
I have created a Roslyn analyzer to check this which marks every usage of such attribute (if used more than once) and allows user to pick fixture called "Leave this attribute occurrence and delete all others".
Now within FixProvider I need to return new modified Solution. It's not difficult to modify every Document that requires the fix (by using SyntaxRewriter to modify SyntaxTree inside). However, I have no idea how to modify Solution or Project - they don't have any method like "ReplaceProject"/"ReplaceDocument".
How to do that?
You could replace the text of a document using the following method:
solution = solution.WithDocumentText(currentDocument.Id,
currentDocumentSyntaxTree.GetText());

adding namespace to xpath

I have classes full of xpaths that now needs a specfic namespace. How can I accomplish this? What would be the easiest way to refactor this code? find replace?
What would be the best way to grab specific nodes in the future, if I don't know the namespaces ahead of time?
susr1 = root.SelectSingleNode("/PurchaseOrderRequest/DocumentHeader/DocumentInformation/DocumentIdentification/Type");
susr1 = root.SelectSingleNode("/PurchaseOrderRequest/ssdh:DocumentHeader/ssdh:DocumentInformation/ssdh:DocumentIdentification/ssdh:Type");
You can try this XML Library. Use XPathElement(). This is a .Net 3.5 solution if you can use it.
XElement root = XElement.Load(file) or .Parse(string)
Then either of your xpath's should work as long as there are not conflicting nodes with the same name (but different namespaces).
XElement susr1 = root.XPathElement("/PurchaseOrderRequest/DocumentHeader/DocumentInformation/DocumentIdentification/Type");
XElement susr1 = root.XPathElement("/PurchaseOrderRequest/ssdh:DocumentHeader/ssdh:DocumentInformation/ssdh:DocumentIdentification/ssdh:Type");
The library should figure out the namespace for you. I cannot test it without example xml to be sure.

.NET XmlSerializer to Element FormDefault=Unqualified XML?

I use C# code more-or-less like this to serialize an object to XML:
XmlSerializer xs1 = new XmlSerializer(typeof(YourClassName));
StreamWriter sw1 = new StreamWriter(#"c:\DeserializeYourObject.xml");
xs1.Serialize(sw1, objYourObjectFromYourClassName);
sw1.Close();
I want it to serialize like this:
<ns0:Header xmlns:ns0="https://mynamespace/">
<SchemaVersion>1.09</SchemaVersion>
<DateTime>2009-12-15T00:00:01-08:00</DateTime>
but instead, it is doing this:
<Header xmlns="https://mynamespace/">
<SchemaVersion xmlns="">V109</SchemaVersion>
<DateTime xmlns="">2010-03-08T18:21:09.100125-08:00</DateTime>
The way it is serializing doesn't work with the XPath I had planned to use, and doesn't match my BizTalk schema. Originally I built the class using XSD.exe from a BizTalk 2006 schema, then I use it for an argument to a WCF web service.
This might be related to an option called element FormDefault = Qualified or Unqualified. In BizTalk, my I have the schema set to "Unqualfiied" which is what I want.
Is there any way for the serializer to output "unqualified" results?
Thanks,
Neal Walters
Update:
Sample attribute on DateTime:
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public System.DateTime DateTime
{
get
{
return this.dateTimeField;
}
set
{
this.dateTimeField = value;
}
}
BizTalk provides for what it calls promoted (or distinguished) fields, which use XPath to pull out values of individual elements. I checked the XPath of BizTalk in a tool called StylusStudio, and Biztalk'x xpath didn't work with the xmlns='' fields above.
The first thing my WCF web service does is to serialize the object to a string (using UTF16 encoding) and store it in an XML column in a SQL database. It is from there I am seeing the above xml sample with the xmlns="".
XPath:
/*[local-name()='Header' and namespace-uri()='https://mynamespace/']/*[local-name()='DateTime' and namespace-uri()='']
The XPATH you're using does not match the namespaces of your XML. Your Header element, for instance, in in the https://mynamespace/, but your XPATH is searching in the http://mynamespace/ namespace.
My question was a bit muddled, so this answer may or may not help someone.
This is a fairly complex scenario, and half of my issues came from trying to simplify it to make an easy post here.
I was actually adding a new element programmatically with a C# routine (see "NewElement" below). The C# code did not set its namespace to an empty string, therefore I believe it is inheriting the namespace of the "Header" element.
I freaked out a little because I was jumping to the conclusion that DateTime should not have the "xmlns=""' when in fact it should. Even though DateTime falls under Header, it does not nor should not inherit the Header's namespace.
In BizTalk, typically only complex types have their own namespace, and DateTime as well as NewElement are simple types.
<Header xmlns="https://mynamespace/">
<SchemaVersion xmlns="">V109</SchemaVersion>
<DateTime xmlns="">2010-03-08T18:21:09.100125-08:00</DateTime>
<NewElement>myvalue</NewElement>
So in effect, the two XML's I posted originally are identical as far as XPath goes. If I insert a new element, I need to make sure it follows the same pattern.
I had written the C# routine to add the element more than a year ago, and it worked fine then, so I wasn't suspect that it was causing this problem.

Localize node texts in treeview using resource files

For a project I need a tree view that allows the user to select a module, which then is displayed in a content area. The project relies heavily on localization and this is provided by the resource files.
Now I discovered today, that the text that are assigned to preset tree view nodes are not contained in the resource files.
So the question is whether there is a way of doing this, short of mapping the elemenst in code. I.e. assigning a name to the node, running over all nodes and pulling the resources from the resouce manager based on the node name.
This is what I am currently doing, however, it just doesn't "feel" right:
private void TranslateNodes(TreeNodeCollection treeNodeCollection) {
var rm = Resources.ResourceManager;
foreach (TreeNode node in treeNodeCollection) {
node.Text = rm.GetString(node.Name + "_Text");
this.TranslateNodes(node.Nodes);
}
}
Thanks!
Your approach looks ok for me, with one exception, it believes that node.Name is unique though entire treeview (which is not correct in general case).
You can use TreeNode.FullPath for unique identify node within treeview. Or alternatively your code can depend on node tag value, but this is highly depend on usage scenario.
And do not forget about calling TreeView's BeginUpdate-EndUpdate.
No suitable, solution found except the one statete in the op ... so closing the question seems apropriate.

How can I load .xsd file to track relationships(nesting) between elements?

I know, where is XmlSchema class in dot net, but it does not allow to load file into it. Is there a clean solution to load xsd file and travel between elements?
You need to use XmlSchemaSet, e.g.:
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.Add(targetNamespace, schemaUri);
schemaSet.Compile();
foreach(XmlSchemaElement element in schemaSet.GlobalElements.Values)
{
// do stuff...
}
EDIT: Sorry for not being clearer.
Where the comment says // do stuff..., what you need to do is traverse the inherited types of each element, which are available under XmlSchemaElement.SchemaType, and the inline type of the element, which is available under XmlSchemaElement.ElementSchemaType.
The MSDN does contain all the the information you're after, but it is somewhat maze-like and requires digging around plus a bit of trial-and-error to work it out.
As per my comment, the following class from one of my open-source side-projects may be of use to you here:
http://bitbucket.org/philbooth/schemabrute/src/tip/LibSchemaBrute/Navigator.cs
I suggest checking out this tool: http://www.altova.com/xmlspy.html. You can create a data model from any XSD file. I've used it in many XML projects.

Categories