Parsing Elmah error logs using a console application - c#

In an effort to minimize time spent on reading error logs, I have created the following small plugin that will parse relevant information contained within Elmah error logs, and eventually produce an Excel spreadsheet. For the time being I am using a WriteLine to test. The issue I am facing is that inside the second foreach loop I am seeing a null reference exception in each of the node.attribute items. The expected outcome of this code is to produce a list of "attribute" values from within the <error> tag of each of the XML documents.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;
namespace ExcelSortingAutomation
{
public class Program
{
public static void Main(string[] args)
{
DirectoryInfo Exceptions = new DirectoryInfo("C:\\ErrorsMay2017");
FileInfo[] ExceptionFiles = Exceptions.GetFiles("*.xml");
foreach (var exception in ExceptionFiles)
{
string xml = "<error></error>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
foreach (XmlNode node in doc.SelectNodes("//error"))
{
string errorId = node.Attributes["errorId"].Value;
string type = node.Attributes["type"].Value;
string message = node.Attributes["message"].Value;
string time = node.Attributes["time"].Value;
Console.WriteLine("{0} - {1} - {2} = {3}", errorId, type, message, time);
}
}
}
}
}
My question is, Why would the logs, which should be pulled and parsed by this point, not be receiving the Attribute values?
Edit 1: upon closer inspection, the XmlNode Node value is returning without "HasAttributes"

The line string xml = "<error></error>"; should be replace with string xml = File.ReadAllText(exception.FullName));

Related

PDF clown field value editing

I am using the PDF clown library to edit a pre-existing PDF (mass autofilling them based on user input) and i'm having trouble changing the form fields (specifically the textfields) value, when attempting to run the code below i will be given this error which is highlighted on the code sample below
" System.InvalidCastException: 'Unable to cast object of type 'org.pdfclown.objects.PdfName' to type 'org.pdfclown.objects.IPdfNumber'.'"
the block of code im having trouble with is a loop that runs through each field and attempts to locate the field matching the name and then altering that fields Value to match the hardcoded string
using org.pdfclown.documents;
using org.pdfclown.documents.contents.composition;
using org.pdfclown.documents.contents.entities;
using org.pdfclown.documents.contents.fonts;
using org.pdfclown.documents.contents.xObjects;
using org.pdfclown.documents.interaction.annotations;
using org.pdfclown.documents.interaction.forms;
using org.pdfclown.documents.files;
using org.pdfclown.objects;
using org.pdfclown.files;
using files = org.pdfclown.files;
using System;
using System.Collections.Generic;
using System.Drawing;
namespace PDFedit
{
class PDFLoader
{
public static void load (string path )
{
string filepath = path;
File file = new File(filepath);
Document document = file.Document;
Form form = document.Form;
Fields fields = form.Fields;
string value = "william";
foreach (Field field in form.Fields.Values)
{
if (field.Name == "Testtext")
{
string typeName = field.GetType().name;
field.value = "data to be written into the field" // this is the line that throws
the error
Console.WriteLine(" Type: " + typeName);
Console.WriteLine(" Value: " + field.Value);
Console.WriteLine(" Data: " + field.BaseDataObject.ToString());
}
};
file.Save();
}
}
}
Apologies if i've committed any fauxpas in asking a question, this is my first post and i'm new to programming outside of a tutorial environment.

Unity 3D C# Strings.XML Methods

I'm attempting to create a method for Unity3D that will allow me to populate a UI via an XML file. i.e. Rather than naming each button and label, they can carry generic names like "progress button" or "large text" Then using the C# script be matched to the verbose name in the XML file.
I have searched extensively for tutorials, examples and guides but each that I have found has been overkill for what I am trying to accomplish.
Ideally, I'd like to provide an XML file using the following structure in the XML file:
<?xml version="1.0" encoding="utf-8"?>
<strings>
<string name="progressBtn">Next</string>
<string name="reverseBtn">Back</string>
<string name="largeText">This is Large Text</string>
</strings>
I know how to dynamically change text in unity by accessing the properties of text-object's so I'm not worried about that step. What I have currently is this:
using UnityEngine;
using System.Collections;
using System.Xml;
using System.IO;
public class textParser : MonoBehaviour
{
public TextAsset targetXMLFile;
public GameObject uiObjectText;
string targetString;
// Use this for initialization
void Start ()
{
checkFile();//Check for strings file.
checkTarget(uiObjectText.name);//Check for the object name in the GUI object
}
// Update is called once per frame
void Update ()
{
//TODO
}
//Check for strings file.
void checkFile()
{
if (targetXMLFile == null) //If is Null, Log an Error
{
print("Error: target text file not loaded!");
}
else // If something, log the file name
{
print(targetXMLFile.name + " Target text file loaded!");
}
}
//Check for the object name in the GUI object
void checkTarget(string target)
{
if (target == null) //If is Null, Log an Error
{
print("Error: Unable to extract target ui object name!");
}
else// if something, Log the GUI Object name
{
print("Found: " + target + " In GUI.");
}
}
}
Obviously very basic, but it works. I know I need to use the XML libraries to accomplish my search (String matching I understand). Getting to that step is what eludes me.
Any tutorials that are much more towards this use of XML I'd love to look at, or if anyone could give me an idea of what methods I need to access to accomplish this. Personally ,I'd love to understand the verbose process behind what I am trying to do if anyone could provide a link to example code.
Thanks in Advance!
You can use the Xml.Serialization from .NET:
https://unitygem.wordpress.com/xml-serialisation/
Try something like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string header = "<?xml version=\"1.0\" encoding=\"utf-8\"?><strings></strings>";
XDocument doc = XDocument.Parse(header);
XElement strings = (XElement)doc.FirstNode;
List<List<string>> buttons = new List<List<string>>() {
new List<string>() {"progressBTn", "Next"},
new List<string>() {"reverseBth", "Back"},
new List<string>() {"largeText", "This is Large Text"}
};
foreach(List<string> button in buttons)
{
strings.Add(
new XElement("string", new object[] {
new XAttribute("name", button[0]),
button[1]
}));
}
}
}
}

XmlReader testing of string returned for newline

I am writing a C# class to use for generating email lists to use when a process either succeeds or fails. In running through XmlReader examples from the web, I found that validating the Read() is tougher than it looks.
I can use string.IsNullOrEmpty(x) to test for a null value or and empty node, but it will still blow by that test showing a "\n " in the tooltip for x. Testing for "\n ", '\n ', '\n'. "\n" or char(13) all fail. If I use x.Contains((char)13), it always find it and goes into the code trying to build the email address list. So far, it either always fails or always succeeds.
I found some old posts on stackoverflow where it seemed like the question was the same, but my results don't match with the answers. My environment is Windows 8.1 running Visual Studio 2013 with .Net Framework 4.51. The example from the web I was trying to make work before using the solution in my class is at Microsoft.com
My conversion is below:
using System;
using System.Text;
using System.Linq;
using System.Xml;
using System.Xml.Schema;
using System.IO;
using System.Collections.Generic;
namespace XMLDemo
{
public class project
{
public static void Main()
{
string uri = #"C:\\events\items.xml";
string process_state = "Item";
string emails = StreamEmailAddress(uri, process_state);
}
private static string StreamEmailAddress(string uri, string process_state)
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
XmlReader reader = XmlReader.Create(uri, settings);
string returnValue = "";
reader.MoveToContent();
while (reader.Read())
{
string x = reader.Value;
if ((string.IsNullOrEmpty(x) == false) && (x.Contains((char)13)))
{
returnValue = returnValue + x + "; ";
}
}
Console.WriteLine("Made it to the end: " + returnValue);
return returnValue;
}
}
}
You should use string.IsNullOrWhiteSpace
SOLVED: After futzing with it all day, I looked at it with slightly fresher eyes after posting and saw the blatant error. I was using the incorrect function and trying to resolve line feeds by myself. By replacing IsNullOrEmpty(x) with IsNullOrWhiteSpace(x), I got the string of data as expected. Doing the code with email addresses will be easy now.

Programmatically creating a TFS iteration for a known deep path

Creating a simple iteration path in TFS 2013 is described here. Traversing a whole tree of unknown depth is described here. I need to create an iteration path of which I know the exact path, and which contains sub-directories, as in \{ProjectName}\Iteration\{Year}\{Iteration}
EDIT:
In order to do that safely, I need to first check the existence of the iteration path, which requires me to check the existence of {Year} and {Iteration}. Otherwise an exception is thrown and I'd like to avoid exception-based logic.
I can find only one way of doing that, and it is level by level, using the method CommonStructureService.GetNodesXml(), but then I have to parse XML and I lose the advantage of using the provided API types such as NodeInfo. Is there a better way to check for existence of a deeper child with a known path while retaining the API domain model?
You can create the iterations one by one: Create the node {Year} first, and then create the {Iteration} under {Year}. See following code for details:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
namespace AAAPI
{
class Program
{
static void Main(string[] args)
{
string project = "https://xxx.xxx.xxx.xxx/tfs";
string projectName = "XXX";
string node1 = "Year";
string node2 = "Iter1";
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(project));
tpc.Authenticate();
Console.WriteLine("Creating node" + node1);
var css = tpc.GetService<ICommonStructureService>();
string rootNodePath = string.Format("\\{0}\\Iteration", projectName);
var pt = css.GetNodeFromPath(rootNodePath);
css.CreateNode(node1, pt.Uri);
Console.WriteLine("Creating" + node1 + "Successfully");
Console.WriteLine("Creating node" + node2);
string parentNodePath = string.Format("\\{0}\\Iteration\\{1}", projectName, node1);
var pt1 = css.GetNodeFromPath(parentNodePath);
css.CreateNode(node2, pt1.Uri);
Console.WriteLine("Creating" + node2 + "Successfully");
Console.ReadLine();
}
}
}
As no valid answers have come I'm going to assume the following answer:
No, there's no way to read any deeper part than the top level while retaining the API typed domain model.
XML is currently the only option.

Read from a XML file to an Array node by node in C#

The XML file is like this,There are about 20 Nodes(modules) like this.
<list>
<module code="ECSE502">
<code>ECSE502</code>
<name>Algorithms and Data structures</name>
<semester>1</semester>
<prerequisites>none</prerequisites>
<lslot>0</lslot>
<tslot>1</tslot>
<description>all about algorythms and data structers with totorials and inclass tests</description>
</module>
</list>
I did the following code. But when I debugged it it even didn't went inside to foreach function.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
namespace ModuleEnrolmentCW
{
class XMLRead
{
public string[] writeToXML(string s)
{
string text = s;
string[] arr = new string[6];
XmlDocument xml = new XmlDocument();
xml.Load("modules.xml");
XmlNodeList xnList = xml.SelectNodes("list/module[#code='" + text + "']");
foreach (XmlNode xn in xnList)
{
arr[0] = xn.SelectSingleNode("code").InnerText;
arr[1] = xn.SelectSingleNode("name").InnerText;
arr[2] = xn.SelectSingleNode("semester").InnerText;
arr[3] = xn.SelectSingleNode("prerequisites").InnerText;
arr[4] = xn.SelectSingleNode("lslot").InnerText;
arr[5] = xn.SelectSingleNode("tslot").InnerText;
}
return arr;
}
}
}
Please tell me where is the wrong??
Here is the rest of the code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ModuleEnrolmentCW
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string selected;
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
XMLRead x = new XMLRead();
selected = (string)listBox1.SelectedItem;
string[] arr2 = x.writeToXML(selected);
label11.Text = arr2[0];
}
}
}
Make sure you are specifying correct path for your xml file.
It is working for me.
This line:
XmlNodeList xnList = xml.SelectNodes("list/module[#code='" + text + "']");
should read:
XmlNodeList xnList = xml.SelectNodes("list/module"); //Does not answer full scope of the question
Edit following a reread of the question:
The OP's code works fine in my tests. Either the file path is not correct, or the the string s passed into text matches the case of the Code value by which you are reading the nodes.
The SelectNodes XPath as you have it is case sensitive.
You appear to be working with XPath V1.0 which doesn't appear to support out of the box case insensitivity if that's a issue. See this link for a way to perform case insensitive XPath searches: http://blogs.msdn.com/b/shjin/archive/2005/07/22/442025.aspx
See also this link: case-insensitive matching in xpath?
Your code is correct, if the input is really the one you shown, and s point to an actual present code. Since you are pointing the file by a relative path, ensure you are loading the file you really expect.
Found the error. I was passing a wrong value to writeToXML method. Insted of passing code, I have passed name

Categories