Click here to Skip to main content
15,895,667 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, I'm trying to create a program having the following steps:
1) Get all xml files from a user given path
2) Open each of the files (if any) and search for nodes <institution> where it is in the format <funding-source><institution-wrap><institution>...</institution></institution-wrap></funding-source>
3) Get the value of the nodes <institution> and search the exact value in the database xml inside the nodes <skosxl:literalForm xml:lang="...">
4) If found, get the attribute value of its parent node <skos:Concept rdf:about="..."> minus the string http://dx.doi.org/
5) Add a node <institution-id institution-id-type="fundref"> in the xml file after the <institution> node with the value like <funding-source><institution-wrap><institution>...</institution><institution-id institution-id-type="fundref">VALUE of the rdf:about attribute</institution-id></institution-wrap></funding-source>
Here is a sample input file and the desired output for that file.

What I have tried:

C#
string pathToUpdatedFile = @"D:\test\test2\Jobs\IEEE_sample - Copy.xml";
			var files=Directory.GetFiles(pathToUpdatedFile,"*.xml");
			foreach (var file in files)
			{
				var fundingDoc = XDocument.Load(@"D:\test\test2\Jobs\fundref.xml");
				XNamespace rdf=XNamespace.Get("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
				XNamespace skosxl = XNamespace.Get("http://www.w3.org/2008/05/skos-xl#");
				XNamespace skos=XNamespace.Get("http://www.w3.org/2004/02/skos/core#");
				
				var targetAtt = fundingDoc.Descendants(skos+"Concept").Elements(skosxl+"prefLabel")
					.ToLookup(s => (string)s.Element(skosxl+"literalForm"), s => (string)s.Parent.Attribute(rdf+"about"));
				XDocument outDoc = XDocument.Load(pathToUpdatedFile,LoadOptions.PreserveWhitespace);
				foreach (var f in outDoc.Descendants("funding-source").Elements("institution-wrap"))
				{
					if (f.Element("institution-id") == null)
					{
						var name = (string)f.Element("institution");
						var x = targetAtt[name].FirstOrDefault(); // just take the first one
						if (x != null)
							
							f.Add(new XElement("institution-id", new XAttribute("institution-id-type","fundref"),x.Substring(@"http://dx.doi.org/".Length)));
					}
					outDoc.Save(file);
				}
				
				Console.ReadLine();

But it is not doing what I described above...can anyone help?
Also, there could be identical <skosxl:literalForm xml:lang="..."> values in the database xml file (but with different attrib (rdf:about) values), in that case take the value of the first match and write a txt file saying the value appears multiple times in the database or something like that just to notify the user if the correct value is inserted in the file.
Posted
Updated 20-Mar-18 17:26pm

1 solution

1) Read xml file into string
2) Deserialize the xml to a class
3) Update the class
4) Serialize the class back to xml (string)
5) Save xml

Use Paste Special in VS to get classes from xml / json.
 
Share this answer
 
Comments
Member 12692000 21-Mar-18 6:10am    
What is wrong with my approach?? I think a little tweak in that code could do just fine...Anyways, can you show some code for your approach in the case
[no name] 21-Mar-18 13:08pm    
Nothing wrong with your approach ... if it works.

I showed you what I sometimes use; in case you want to consider an alternate approach (which is what I do when the other does not work "easy" enough).

I use LINQ to XML; but only when it suits the situation. And since your "situation" was not working ... But "tweak" away!!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900