|
Hi
This is driving me nuts.
Besides my first structure containing "drive" information, I also have a registry content XML file.
I thought I'd just apply some analogy and it sort of works but for some reason I do not seem to be able to dig deeper into the structure than <value> but I would like to get the value of <action>, <type> and <content> (inside if <value> too.
So here is the structure:
<Registry>
<RootKey>
<Name>HKEY_LOCAL_MACHINE</Name>
<Action>None</Action>
<ContainedKeys>
<Key>
<Name>SOFTWARE</Name>
<Action>None</Action>
<ContainedKeys>
<Key>
<Name>Classes</Name>
<Action>None</Action>
<ContainedKeys>
<Key>
<Name>Installer</Name>
<Action>None</Action>
<ContainedKeys>
<Key>
<Name>Features</Name>
<Action>None</Action>
<ContainedKeys>
<Key>
<Name>8CD5D2FB0DBCDD64A8D2AB1D09CAF271</Name>
<Action>Created</Action>
<ContainedValues>
<Value>
<Name>ClientPrograms</Name>
<Action>Created</Action>
<After>
<Data>
<Type>REG_SZ</Type>
<Contents></Contents>
</Data>
</After>
</Value>
<Value>
<Name>DataFiles</Name>
<Action>Created</Action>
<After>
<Data>
<Type>REG_SZ</Type>
<Contents>Server</Contents>
</Data>
</After>
</Value>
Using the example that Richard gave, my code is:
<pre
IList<string> Regs = document.Descendants("Value").Select(GetFullPathtoKey).ToList();
static string GetFullPathtoKey(XElement fileElement)
{
var names = new HashSet<XName> { "RootKey", "Key", "Value","Type", "Name", "Data", "Contents" };
IEnumerable<string> pathParts = fileElement.AncestorsAndSelf()
.Where(el => names.Contains(el.Name))
.Select(el => (string)el.Element("Name"))
.Reverse();
return string.Join("\\", pathParts);
}
<pre lang="text">
That works fine and a list entry is for instance:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Features\8CD5D2FB0DBCDD64A8D2AB1D09CAF271\ClientPrograms
But if I extend the Path to include , it will just not work:
Like:
<pre
IList<string> Regs = document.Descendants("Data").Select(GetFullPathtoKey).ToList();
static string GetFullPathtoKey(XElement fileElement)
{
var names = new HashSet<XName> { "RootKey", "Key", "Value","Type", "Name", "Data", "Contents" };
IEnumerable<string> pathParts = fileElement.AncestorsAndSelf()
.Where(el => names.Contains(el.Name))
.Select(el => (string)el.Element("Contents"))
.Reverse();
return string.Join("\\", pathParts);
}
<pre lang="text">
will give \\\\\\\\ for the first entry and
\\\\\\\Server for the second.
No I can create three lists for the path with Value, the Action and the Content, but that seems to be overkill.
After extracting the Path: "HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Features\8CD5D2FB0DBCDD64A8D2AB1D09CAF271\ClientPrograms"
how can I derive easily the Action, Type and the Content???
I have been piddling with this for the whole weekend without success. I guess I do not understand what the difference is
between the path to <value> and the path to .
Thanks a lot for any help!!!!
|
|
|
|
|
The problem with your second method is that your <Value> , <Key> and <RootKey> elements don't contain an element called "Contents". That means that you'll get the value from the <Contents> element under the <Data> element, and an empty string for each ancestor element.
If you just want to append the value from the <Contents> element to the path, then use:
static string GetFullPathToKey(XElement dataElement)
{
var names = new HashSet<XName> { "RootKey", "Key", "Value", "Data" };
IEnumerable<string> pathParts = dataElement.AncestorsAndSelf()
.Where(el => names.Contains(el.Name))
.Select(el => (string)el.Element("Name") ?? (string)el.Element("Contents"))
.Reverse();
return string.Join("\\", pathParts);
}
IList<string> Regs = document.Descendants("Data").Select(GetFullPathToKey).ToList();
If you want to include the <Action> , <Type> and <Content> in a different format, then try something like this:
static string GetFullPathToKey(XElement dataElement)
{
var names = new HashSet<XName> { "RootKey", "Key", "Value" };
IEnumerable<string> pathParts = dataElement.AncestorsAndSelf()
.Where(el => names.Contains(el.Name))
.Select(el => (string)el.Element("Name"))
.Reverse();
string fullPath = string.Join("\\", pathParts);
string details = string.Format(" {{ Action: '{0}', Type: '{1}', Contents: '{2}' }}",
(string)dataElement.Element("Action"),
(string)dataElement.Elements("After").Elements("Data").Elements("Type").FirstOrDefault(),
(string)dataElement.Elements("After").Elements("Data").Elements("Contents").FirstOrDefault());
return fullPath + details;
}
IList<string> Regs = document.Descendants("Value").Select(GetFullPathToKey).ToList();
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thank you Richard!!!
I really appreciate your help.
|
|
|
|
|
You must be a true XML Linq wiz!
|
|
|
|
|
Thank you everybody
Sorry, I did not get the formatting right ...
Richard, the "Descendants" look very promising.
Bernhard, thanks for the xsd tip, I'll have to check this out - again, first time XML user.
Dave, thanks for the reformatting. No I do not want to use XML as a database,
but this is the output of a disk analysis tool, that I need a human (management ) readable report of.
Thanks again
|
|
|
|
|
eblaschka wrote: this is the output of a disk analysis tool, that I need a human (management ) readable report of.
That would have helped if you put that in your original post. I wouldn't have suggested you start with the classes then.
I would agree with Bernhards use of the XSD tool to generate the classes for you. You could still use link over that object graph to your report data.
|
|
|
|
|
Thank you Dave for cleaning up my XML code, I really screwed up the format.
I definitely do not want to use XML as a database, but I do have an output file that I have to make human (rather: Management ) readable for reports.
Thanks Bernhard, I will have to look into the xsd stuff.
Thanks Richard, your "Descendant" method. It works great, BUT only if I cut the file between <drives> part. (The Structur is bigger).
That is not a big issue, but is there something like "get everything from <file> and <drive> " ???
(How does "GetFullPath" know where to stop?)
Thanks a lot to all.
|
|
|
|
|
If you reply to someone's message, then they get notified that you've replied. If you reply to yourself, then nobody else will be notified.
There's almost certainly a way to make it work, but without knowing the full structure of your XML file, we can only guess:
static string GetFullPath(XElement fileElement)
{
var names = new HashSet<XName> { "Drive", "Folder", "File" };
IEnumerable<string> pathParts = fileElements.AncestorsAndSelf()
.TakeWhile(el => el.Name != "Drives")
.Where(el => names.Contains(el.Name))
.Select(el => (string)el.Element("Name"))
.Reverse();
return string.Join("\\", pathParts);
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
|
Hi,
I have a C# WIndows Application Form with MySQL backend (which can be on Windows or Linux Server).
I want my application to send email notifications about the contracts data in my applications (contracts expiry notifications) by email according to a schedule(probably daily once)
What's the best cross platform way to do it which will work on windows and linux server?
Thanks
Technology News @ www.JassimRahma.com
|
|
|
|
|
There are some scripting languages available which can be used both on Linux and Windows, e.g. PERL. But do you really want to learn a new programming language just for that task, including all the WTFs of scripting languages?
I'd suggest to use a Windows Service which connects to your database to retrive the information and then sends the emails. Alternatively, a "normal" Windows console application is started as a "scheduled task" and does that job.
|
|
|
|
|
WIndows Services is fine but not when the user is away or traveling and don't have access to his PC which means the windows services will not run because his PC is switched off because the server side could be linux not windows!
Technology News @ www.JassimRahma.com
|
|
|
|
|
Jassim Rahma wrote: the windows services will not run because his PC is switched off Well, I do not know of any application or service to run on a switched-off computer...
|
|
|
|
|
What is Framework of .net and its features?
Shail...
|
|
|
|
|
Here you go. There's plenty of good material here[^].
|
|
|
|
|
Wow, Pete, you are a genius!
|
|
|
|
|
You can google this to find enough resources.Your question should be as specific and concise as possible.It would be good if it is related to a practical real time issue
Thanks
Do not forget to comment and rate the article if it helped you by any means.
|
|
|
|
|
I'm working on a WPF app that call through a ASP.Net MVC 4 Web API.
I make the following call:
public CompanyInfoAddressEntity AddCompanyInfoAddress(CompanyInfoAddressEntity entity)
{
WebAPIExecutor webAPIExecutor = new WebAPIExecutor("/CompanyInfoAddresses/AddCompanyInfoAddress/");
webAPIExecutor.AddParameter(entity, "entity");
CompanyInfoAddressEntity results = webAPIExecutor.Execute<CompanyInfoAddressEntity>();
return results;
}
When I call into Execute, it runs fine and the entity is passed to the controller, BL, and DAL fine. But when it returns back to here, the 'entity' object is null.
I have no idea what's wrong. How do I debug this sort of problem?
If it's not broken, fix it until it is
|
|
|
|
|
Google has no results for WebAPIExecutor - is that a custom class you've written?
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
It's a wrapper class for REST that I wrote. I'm 100% sure it's not the problem, but here's the code anyhow:
public class WebAPIExecutor
{
#region Private Fields
private RestClient client;
private RestRequest request;
#endregion
#region Properties
public string ServerName { get; private set; }
public string ServerAddress { get; private set; }
#endregion
#region CTOR
public WebAPIExecutor()
{
setupServerURL();
}
public WebAPIExecutor(string url, Method method = Method.POST)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("Url");
}
setupServerURL();
client = new RestClient(ServerAddress);
client.AddHandler("text/plain", new JsonDeserializer());
request = new RestRequest(url, method)
{
RequestFormat = RestSharp.DataFormat.Json
};
}
#endregion
#region Public Methods
public void AddParameter(object value, string name = "")
{
if (value == null)
{
throw new ArgumentNullException("value");
}
Type type = value.GetType();
bool isPrimitive = type.IsPrimitive;
if(isPrimitive || type == typeof(string) || type == typeof(decimal))
{
if (string.IsNullOrEmpty(name) && request.Method == Method.GET)
{
throw new ArgumentNullException("Parameter 'Name' cannot be empty for Get requests");
}
request.AddParameter(name, value);
}
else
{
request.AddBody(value);
}
}
public T Execute<T>() where T : new()
{
if (request.Resource.Trim().ToLower().Contains("controller"))
{
string message = string.Format("Controller names cannot contain the word 'Controller'. Called from request {0}", request.Resource);
MessageBox.Show(message, "WebAPI Warning", MessageBoxButton.OK, MessageBoxImage.Exclamation);
throw new Exception(message);
}
var url = client.BaseUrl + request.Resource;
IRestResponse<T> result = client.Execute<T>(request);
int resultValue = (int)result.StatusCode;
if (resultValue >= 299)
{
string message = string.Format("An error occured calling the WebAPI. {0} The status code is '{1}'. {2} The error message is {3}",
Environment.NewLine, result.StatusCode, Environment.NewLine, result.Content );
MessageBox.Show(message, "WebAPI Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);
throw new Exception(message);
}
return result.Data;
}
public void Execute()
{
IRestResponse result = null;
try
{
result = client.Execute(request);
int resultCode = (int)result.StatusCode;
if (resultCode > 299)
{
string message = string.Format("An error occured calling the WebAPI. {0} The status code is '{1}'. {2} The error message is {3}",
Environment.NewLine, result.StatusCode, Environment.NewLine, result.Content );
MessageBox.Show(message, "WebAPI Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);
throw new Exception(message);
}
}
catch (Exception e)
{
throw e;
}
}
#endregion
#region Private Methods
private void setupServerURL()
{
ServerName = ConfigurationManager.AppSettings["servername"];
string ipaddress = ConfigurationManager.AppSettings["ipaddress"];
string port = ConfigurationManager.AppSettings["port"];
ServerAddress = string.Format("http://{0}:{1}/api", ipaddress, port);
}
#endregion
}
}
If it's not broken, fix it until it is
|
|
|
|
|
Are RestClient , RestRequest and IRestResponse from Phil Haack's RestSharp[^] project? If so, are you using the latest version?
Have you tried calling the non-generic Execute method to make sure the returned Content and ContentType are what you were expecting?
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
struct Connection *Database_open(const char *filename, char mode)
{
struct Connection *conn = malloc(sizeof(struct Connection));
if(!conn) die("Memory error");
conn->db = malloc(sizeof(struct Database));
if(!conn->db) die("Memory error");
if(mode == 'c') {
conn->file = fopen(filename, "w");
} else {
conn->file = fopen(filename, "r+");
if(conn->file) {
Database_load(conn);
}
}
if(!conn->file) die("Failed to open the file");
return conn;
}
|
|
|
|
|
it just check the mode you passed as a parameter is equal to 'c'. If it is equal to 'c' then create an empty file for output operations ("w"). else open a file for update ("r+") (both for input and output).
|
|
|
|
|
|
You are welcome
|
|
|
|
|