XMl parsing in c# 4.0 - c#-4.0

i have the following xml to be parsed
<config>
<ParametricTesting>Y</ParametericTesting>
<FunctionalTesting>Y</FunctionalTesting>
<Utilities>N</Utilities>
<CommonApi>N</CommonApi>
<ClientData>N</ClientData>
<DataSourceTest>Y<DataSourceTest>
<Excel>
<ExcelFilePath>myexcel1.xlsx</ExcelFilePath>
</Excel>
<Access>
<AccessDB> </AccessDB>
</Access>
<Sql>
<SqlConnectionString> </SqlConnectionString>
</Sql>
<RunnerConsole>N</RunnerConsole>
<Schedular>N</Schedular>
</config>
I am using xmlreader to read the xml but since i am new to c# so i don't know why the code is breaking after reading second tag i.e ParametericTesting.
code:
string ConfigXml = Path.GetFullPath("Config.xml");
XmlReader xmlReader = XmlReader.Create(ConfigXml);
while (xmlReader.Read()) {
if ((xmlReader.NodeType== XmlNodeType.Element) && xmlReader.Name.Equals("ParametricTesting")) {
// TODO : write code relevant for parametric testing
xmlReader.Read();
}
else if ((xmlReader.NodeType== XmlNodeType.Element)&& xmlReader.Name.Equals("DataSourceTest")) {
string Datasource = xmlReader.GetAttribute("DataSourceTest");
if (Datasource.Equals("Y")) {
if (xmlReader.Name.Equals("Excel") && (xmlReader.NodeType == XmlNodeType.Element)) {
string excelfile = xmlReader.GetAttribute("ExcelFilePath");
string ExcelPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\Files\\" + excelfile;
objExcel.DataSourceName = excelfile;
objExcel.Open();
}
}
xmlReader.Read();
}
xmlReader.Read();
}
My code is not reading element beyond parametricTesting . Please help.

you open tag of "ParametricTesting" in the config.xml is different from the closing tag. correct it and that line passes.
also, you don't close the tag "DataSourceTest"
here is the fixed XML:
<config>
<ParametricTesting>Y</ParametricTesting>
<FunctionalTesting>Y</FunctionalTesting>
<Utilities>N</Utilities>
<CommonApi>N</CommonApi>
<ClientData>N</ClientData>
<DataSourceTest>Y</DataSourceTest>
<Excel>
<ExcelFilePath>myexcel1.xlsx</ExcelFilePath>
</Excel>
<Access>
<AccessDB> </AccessDB>
</Access>
<Sql>
<SqlConnectionString> </SqlConnectionString>
</Sql>
<RunnerConsole>N</RunnerConsole>
<Schedular>N</Schedular>
</config>

Related

C# SharePoint CSOM change file properties after upload

I have searched and found several examples of how to do this, but I can't make them work - well part of it doesn't work.
I can perform the file upload, but the following attempt to change properties fail.
I'm attempting to upload a file from a base64 payload - this part works - but when I afterwards attempt to edit the properties (custom column) associated with the file, the code fails.
Here is the code (simplified for readability):
(note that props is a collection of custom objects (FileProperty) with a name and a value attribute).
using (ClientContext context = new ClientContext("<sharepoint_server_url>"))
{
context.Credentials = new SharePointOnlineCredentials(<usr>,<secure_pwd>);
using (System.IO.MemoryStream ms = new System.IO.MemoryStream(Convert.FromBase64String(<base64_content>)))
{
File.SaveBinaryDirect(context, <relative_path>, ms, true);
}
// file is uploaded - so far so good!
// attempt to edit properties of the file.
if (props != null)
{
if (props.Count > 0)
{
File newFile = context.Web.GetFileByServerRelativeUrl(<relative_path>);
context.Load(newFile);
context.ExecuteQuery();
newFile.CheckOut();
ListItem item = newFile.ListItemAllFields;
foreach (FileProperty fp in props)
{
item[fp.name] = fp.value;
}
item.Update();
newFile.CheckIn(string.Empty, CheckinType.OverwriteCheckIn);
}
}
}
This code throws an exception in the part where I try to update the properties.
Message: The file was not found.
Can anyone tell me what is wrong with this example or provide another example on how to do this?
Also, a question - is there a way to address a file by a unique ID which is the same regardless of where in the SharePoint server the file is located or moved to?
I hope someone can help me out - thanks :)
Ok, I found a solution to my problem. I don't know why this works better, it just does.
For all I know, I'm doing the exact same thing, just in another way - maybe someone else who knows more about SharePoint than me (which isn't much) can explain why this works while the first example I posted doesn't.
Previous to the code shown, I ensure that <site_url> doesn't end with "/" and that <library_name> doesn't start or end with "/" and that <file_name> doesn't start or end with "/".
With the code below I can uplaod a file and update properties, in my case i changed "Title" and a custom column "CustCulomnA" and it workes.
using (ClientContext context = new ClientContext(<site_url>))
{
context.Credentials = new SharePointOnlineCredentials(<usr>, <secure_pwd>);
FileCreationInformation fci = new FileCreationInformation()
{
Url = <file_name>,
Content = Convert.FromBase64String(<base64_content>),
Overwrite = true
};
Web web = context.Web;
List lib = web.Lists.GetByTitle(<library_name>);
lib.RootFolder.Files.Add(fci);
context.ExecuteQuery();
response.message = "uploaded";
if (props != null)
{
if (props.Count > 0)
{
File newFile = context.Web.GetFileByUrl(<site_url> +"/"+ <library_name> + "/" + <file_name>);
context.Load(newFile);
context.ExecuteQuery();
newFile.CheckOut();
ListItem item = newFile.ListItemAllFields;
foreach (FileProperty fp in props)
{
item[fp.name] = fp.value;
}
item.Update();
newFile.CheckIn(string.Empty, CheckinType.OverwriteCheckIn);
context.ExecuteQuery();
Make sure the file server relative url is valid in this case.
For example if the complete url is:
https://zheguo.sharepoint.com/sites/test/Shared%20Documents/test.jpg
Then relative url should be
/sites/test/Shared%20Documents/test.jpg
And you can also use GetFileByUrl method, passing the complete file url like this:
clientContext.Credentials = new SharePointOnlineCredentials(userName, securePassword);
Web web = clientContext.Web;
clientContext.Load(web);
clientContext.ExecuteQuery();
File file = web.GetFileByUrl("https://zheguo.sharepoint.com/sites/test/Shared%20Documents/test.jpg");
clientContext.Load(file);
clientContext.ExecuteQuery();
file.CheckOut();
ListItem item = file.ListItemAllFields;
item["Title"] = "Test";
item.Update();
file.CheckIn(string.Empty, CheckinType.OverwriteCheckIn);
clientContext.ExecuteQuery();
}

JSON to XML conversion in Node JS service (using xml2js)

I need some help/advice with JSON to XML conversion in Node js.
I have a service that gets a JSON object in request body that needs to convert to XML. I am able to achieve this using node-xml2js for json inputs with maximum one level of nested objects. But, it gets way more complicated with nested objects having attribute values. Attributes should be identified first, prefixed with $ sign and enclosed in curly braces before parsing through xml2js to get correct xml.
Is there a better way of doing this where this complicated layer of reformatting the json input can be simplified?
xml2js can converts this:
{
"Level1":{ "$":{ "attribute":"value" },
"Level2": {"$":{"attribute1":"05/29/2020",
"attribute2":"10","attribute3":"Pizza"}}
}
to this:(which is correct):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Level1 attribute="value">
<Level2 attribute1="05/29/2020" attribute2="10" attribute3="Pizza"/>
</Level1>
But actual json input is this:
{
"Level1":{"attribute":"value",
"Level2": {"attribute1":"05/29/2020",
"attribute2":"10","attribute3":"Pizza"} }
}
Expected same result:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Level1 attribute="value">
<Level2 attribute1="05/29/2020" attribute2="10" attribute3="Pizza"/>
</Level1>
Please let me know if you have worked on similar requirements. Appreciate any help.
Thank you.
This would be a way to change the object back to the format expected in the library, although it assumes that all non object keys are supposed to be attributes (is that a valid assumption for your application?)
function groupChildren(obj) {
for(prop in obj) { // consider filtering for own properties (vs from prototype: for(prop of Object.keys(obj)) {
if (typeof obj[prop] === 'object') {
groupChildren(obj[prop]);
} else {
obj['$'] = obj['$'] || {};
obj['$'][prop] = obj[prop];
delete obj[prop];
}
}
return obj;
}
and then used like so:
var xml2js = require('xml2js');
var obj = {
Level1: {
attribute: 'value',
Level2: {
attribute1: '05/29/2020',
attribute2: '10',
attribute3: 'Pizza'
}
}
};
var builder = new xml2js.Builder();
var xml = builder.buildObject(groupChildren(obj));
which prints out:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Level1 attribute="value">
<Level2 attribute1="05/29/2020" attribute2="10" attribute3="Pizza"/>
</Level1>
you can use this library :nashwaan/xml-js
Like This:
let xmlJ=require('xml-js');
let parseToJson=(xml)=>{
return new Promise(resolve => {
let convert;
convert=xmlJ.xml2json(xml,{compact:true});
resolve(convert);
});
};

Parsing attributes and Values using Groovy's XmlParser

I have the following part of an XML file:
<properties>
<project.version>module.version</project.version>
<ie.version>17-8-103</ie.version>
<leg_uk.version>17-6-6</leg_uk.version>
<leg_na.version>17-8-103</leg_na.version>
</properties>
I want to generate a file with the following content:
ie.project.version = 17-8-103
leg_uk.project.version = 17-8-103
How to generate such file?
Is that what You're looking for?
def txt = """<properties>
<project.version>module.version</project.version>
<ie.version>17-8-103</ie.version>
<leg_uk.version>17-6-6</leg_uk.version>
<leg_na.version>17-8-103</leg_na.version>
</properties>"""
def xml = new XmlParser().parseText(txt)
new File('tmp').withWriter { w ->
xml.children().each {
w << "${it.name()}=${it.value().text()}\n"
}
}

Extracting Extended Data from KML using Javascript

I have a placemark in a KML that looks something like this
<Placemark>
<id>test345</id>
<name>Images from KML file</name>
<ExtendedData>
<Data name="type">
<value>images</value>
</Data>
</ExtendedData>
<Point>
<coordinates>-122.448425,37.802907,0</coordinates>
</Point>
I'm attempting to extract the ExtendedData information out of this placemarker on a click event:
google.earth.addEventListener(kmlObject, 'click', function(event) {
event.preventDefault();
var kmlPlacemark = event.getTarget();
});
An alternative solution would be to get the kmlObject from the kmlPlacemarker, any ideas?
Given the placemark the Google Earth API provides two methods to access the ExtendedData element.
getBalloonHtml()
getBalloonHtmlUnsafe()
API Reference:
https://developers.google.com/earth/documentation/reference/interface_kml_feature
You can find a working example in the Google Code Playground here:
https://code.google.com/apis/ajax/playground/?exp=earth#extended_data_in_balloons
If you wanted to get the raw KML for extended data then you could fetch the KML representation and parse it as an XML document.
var output = placemark.getKml();
Just to say I posted about just this issue on the support forum for the plug-in: https://code.google.com/p/earth-api-samples/issues/detail?id=16
Here is a method I cobbled together to provide support for getExtendedData. It takes a string of Kml as the argument via 'feature.getKml();` It returns any extended data elements that have values in a key[value] object. It expects the extended data to be in the format:
<Data name="Foo">
<value>bar</value>
</Data>
Tested in XP - FF3.0, IE7, Chrome
function getExtendedData(kmlString) {
var xmlDoc = null;
var keyValue = [];
//Parse the kml
try {
//Internet Explorer
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.loadXML(kmlString);
} catch(e) {
try {
//Firefox, etc.
var parser = new DOMParser();
xmlDoc = parser.parseFromString(kmlString,"text/xml");
}
catch(e) {
//Failed to parse
alert(e.message);
return;
}
}
// Get all the named elements
var data = xmlDoc.getElementsByTagName("Data");
// Iterate through the data elements
for(var i=0; i<data.length; i++) {
if(data[i].getAttribute("name") &&
data[i].getElementsByTagName("value").length > 0) {
// Get the name and value
var name = data[i].getAttribute("name");
var value = data[i].getElementsByTagName("value")[0].firstChild.data;
// Assign them to the keyValue object
keyValue[name] = value;
}
}
return keyValue;
}
Usage
// where 'feature' is the object with the extended data
var data = getExtendedData(feature.getKml());
for (var name in data) {
var value = data[name];
alert(name + '=' + value); // e.g. type=images
}
It is actually possible to access the ExtendedData elements via the DOM APIs, although they're not particularly well-documented anywhere.
I found them while grepping around inside some of the resource (.rcc) files packaged with the Plugin.
Assuming a simple Placemark sample similar to yours:
<Placemark id="testmark">
<!-- other stuff... -->
<ExtendedData>
<Data name="someDataUrl">
<displayName>URL Representing some Data</displayName>
<value>http://example.com/#hello</value>
</Data>
</ExtendedData>
</Placemark>
Then (once it's fetched/parsed/loaded into Earth, you can access it something like:
var mark = ge.getElementById('testmark');
var extDataObj = mark.getExtendedData();
var extDataOut = Array(extDataObj.getDataCount());
for (var i = 0; i < extDataObj.getDataCount(); i++) {
var item = extDataObj.getData(i);
var details = { name: item.getName(),
displayName: item.getDisplayName(),
value: item.getValue()
};
extDataOut[i] = details;
}
console.dir(extDataOut);
Haven't tested it for performance vs the .getKml() and feed to an external parser approach, and the lack of official documentation might mean it's not fully functional or supported, but in all testing so far it seems to do ok. I haven't yet found a way to access any of the more complicated SchemaData type structures, only the simple <data name=''><value>... form.

Flex embedded string resource encoding

I embed a text file into my Flex project and read its contents using code like this:
[Embed(source = "../../data/abc.txt", mimeType = "application/octet-stream")]
private var r_Abc:Class;
...
var xx:ByteArray = new r_Abc();
var abc:String = xx.toString();
The contents of the file is abc. The problem is that the string loaded from the file is not comparable to other strings even though when printed or viewed in the debugger (in FlashDevelop) it seems to be perfectly fine.
trace(abc); // abc
trace("abc" == abc); // false
How do I convert it into a proper string? I tried to use the string methods such as substring to create a copy, but that does not seem to be the solution.
Here's my sample:
<?xml version="1.0" encoding="utf-8"?>
<s:Application minWidth="955" minHeight="600"
creationComplete="creationCompleteHandler(event)"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import mx.core.ByteArrayAsset;
import mx.events.FlexEvent;
// my file is "ABC "
// strangely enough if I remove the space at the end the string in code is empty
[Embed(source="data/abc.txt", mimeType="application/octet-stream")]
private var abcFile:Class;
protected function creationCompleteHandler(event:FlexEvent):void
{
var abcByteArray:ByteArrayAsset = ByteArrayAsset(new abcFile());
var abc:String = abcByteArray.readUTFBytes(abcByteArray.length);
trace(abc); // ABC (has a space at the end)
trace(abc == "ABC "); // true, but notice the space at the end
}
]]>
</fx:Script>
</s:Application>
My suggestion is to check for trailing spaces, new lines. Also try to place some sort of an EOF character at the end of the file.

Resources