-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 281b2af
Showing
14 changed files
with
950 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
// Use IntelliSense to find out which attributes exist for C# debugging | ||
// Use hover for the description of the existing attributes | ||
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"name": ".NET Core Launch (console)", | ||
"type": "coreclr", | ||
"request": "launch", | ||
"preLaunchTask": "build", | ||
// If you have changed target frameworks, make sure to update the program path. | ||
"program": "${workspaceFolder}/QFXparser.TestApp/bin/Debug/netcoreapp2.0/QFXparser.TestApp.dll", | ||
"args": [], | ||
"cwd": "${workspaceFolder}/QFXparser.TestApp", | ||
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window | ||
"console": "internalConsole", | ||
"stopAtEntry": false, | ||
"internalConsoleOptions": "openOnSessionStart" | ||
}, | ||
{ | ||
"name": ".NET Core Attach", | ||
"type": "coreclr", | ||
"request": "attach", | ||
"processId": "${command:pickProcess}" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"csharp.format.enable": false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"version": "2.0.0", | ||
"tasks": [ | ||
{ | ||
"label": "build", | ||
"command": "dotnet", | ||
"type": "process", | ||
"args": [ | ||
"build", | ||
"${workspaceFolder}/QFXparser.TestApp/QFXparser.TestApp.csproj" | ||
], | ||
"problemMatcher": "$msCompile" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace QFXparser.Core | ||
{ | ||
public class Parser | ||
{ | ||
public static IEnumerable<Token> Parse(string fileText) | ||
{ | ||
|
||
Token token = new Token(); | ||
|
||
foreach (var character in fileText) | ||
{ | ||
if (character == '<') | ||
{ | ||
if (!token.IsElement) | ||
{ | ||
if (!string.IsNullOrEmpty(token.Content)) | ||
{ | ||
yield return token; | ||
} | ||
token.ClearToken(); | ||
} | ||
|
||
token.IsElement = true; | ||
} | ||
else if (character == '>') | ||
{ | ||
if (!string.IsNullOrEmpty(token.Content)) | ||
{ | ||
yield return token; | ||
} | ||
token.ClearToken(); | ||
} | ||
else | ||
{ | ||
token.AddCharacter(character); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<Company>emaquest.net</Company> | ||
<Product>QFXparser</Product> | ||
<PackageId>QFXparser</PackageId> | ||
<Authors>Emanuele Ramella-Paia</Authors> | ||
<Description>Simple parser for .qfx and .qbo files.</Description> | ||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | ||
</PropertyGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace QFXparser.Core | ||
{ | ||
[NodeName("CCSTMTRS")] | ||
public class Statement | ||
{ | ||
[NodeName("ACCTID")] | ||
public string AccountNum { get; set; } | ||
|
||
[NodeName("BANKTRANLIST")] | ||
public ICollection<Transaction> Transactions { get; set; } = new List<Transaction>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Text; | ||
|
||
namespace QFXparser.Core | ||
{ | ||
public class StatementBuilder | ||
{ | ||
private Statement _statement; | ||
private Transaction _currentTransaction; | ||
private string _fileText; | ||
|
||
public StatementBuilder(string fileNamePath) | ||
{ | ||
using (StreamReader sr = new StreamReader(fileNamePath)) | ||
{ | ||
_fileText = sr.ReadToEnd(); | ||
} | ||
|
||
} | ||
|
||
public StatementBuilder(Stream fileStream) | ||
{ | ||
using (StreamReader sr = new StreamReader(fileStream)) | ||
{ | ||
_fileText = sr.ReadToEnd(); | ||
} | ||
|
||
} | ||
|
||
public Statement Build() | ||
{ | ||
|
||
MemberInfo currentMember = null; | ||
|
||
foreach (var token in Parser.Parse(_fileText)) | ||
{ | ||
if (token.IsElement) | ||
{ | ||
var result = GetPropertyInfo(token.Content); | ||
if (result != null) | ||
{ | ||
switch (result.Type) | ||
{ | ||
case NodeType.StatementOpen: | ||
_statement = new Statement(); | ||
break; | ||
case NodeType.StatementClose: | ||
return _statement; | ||
break; | ||
case NodeType.TransactionOpen: | ||
_currentTransaction = new Transaction(); | ||
break; | ||
case NodeType.TransactionClose: | ||
_statement.Transactions.Add(_currentTransaction); | ||
_currentTransaction = null; | ||
break; | ||
case NodeType.StatementProp: | ||
case NodeType.TransactionProp: | ||
currentMember = result.Member; | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
else | ||
{ | ||
currentMember = null; | ||
} | ||
} | ||
else | ||
{ | ||
if (currentMember != null && currentMember is PropertyInfo) | ||
{ | ||
var property = (PropertyInfo)currentMember; | ||
switch (property.DeclaringType.Name) | ||
{ | ||
case "Statement": | ||
property.SetValue(_statement, token.Content); | ||
break; | ||
case "Transaction": | ||
property.SetValue(_currentTransaction, token.Content); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
return _statement; | ||
} | ||
|
||
private PropertyResult GetPropertyInfo(string token) | ||
{ | ||
var propertyResult = new PropertyResult(); | ||
|
||
if (typeof(Statement).GetCustomAttribute<NodeNameAttribute>().CloseTag == token) | ||
{ | ||
propertyResult.Member = typeof(Statement); | ||
propertyResult.Type = NodeType.StatementClose; | ||
return propertyResult; | ||
} | ||
|
||
if (typeof(Transaction).GetCustomAttribute<NodeNameAttribute>().CloseTag == token) | ||
{ | ||
propertyResult.Member = typeof(Transaction); | ||
propertyResult.Type = NodeType.TransactionClose; | ||
return propertyResult; | ||
} | ||
|
||
if (typeof(Statement).GetCustomAttribute<NodeNameAttribute>().OpenTag == token) | ||
{ | ||
propertyResult.Member = typeof(Statement); | ||
propertyResult.Type = NodeType.StatementOpen; | ||
return propertyResult; | ||
} | ||
|
||
if (typeof(Transaction).GetCustomAttribute<NodeNameAttribute>().OpenTag == token) | ||
{ | ||
propertyResult.Member = typeof(Transaction); | ||
propertyResult.Type = NodeType.TransactionOpen; | ||
return propertyResult; | ||
} | ||
|
||
|
||
var statementMember = typeof(Statement).GetProperties().FirstOrDefault(m => m.GetCustomAttribute<NodeNameAttribute>().OpenTag == token); | ||
|
||
if (statementMember != null) | ||
{ | ||
propertyResult.Member = statementMember; | ||
propertyResult.Type = NodeType.StatementProp; | ||
return propertyResult; | ||
} | ||
|
||
var transactionMember = typeof(Transaction).GetProperties().Where(m => m.GetCustomAttribute<NodeNameAttribute>() != null) | ||
.FirstOrDefault(m => m.GetCustomAttribute<NodeNameAttribute>().OpenTag == token); | ||
|
||
if (transactionMember != null) | ||
{ | ||
propertyResult.Member = transactionMember; | ||
propertyResult.Type = NodeType.TransactionProp; | ||
return propertyResult; | ||
} | ||
|
||
return null; | ||
|
||
} | ||
|
||
} | ||
|
||
internal class PropertyResult | ||
{ | ||
public MemberInfo Member { get; set; } | ||
public NodeType Type { get; set; } | ||
} | ||
|
||
internal enum NodeType | ||
{ | ||
StatementOpen, | ||
StatementClose, | ||
TransactionOpen, | ||
TransactionClose, | ||
StatementProp, | ||
TransactionProp | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace QFXparser.Core | ||
{ | ||
public class Token | ||
{ | ||
private StringBuilder _content; | ||
|
||
public Token() | ||
{ | ||
_content = new StringBuilder(); | ||
} | ||
|
||
public bool IsElement { get; set; } = false; | ||
|
||
public string Content | ||
{ | ||
get | ||
{ | ||
return _content.ToString().Trim(); | ||
} | ||
} | ||
|
||
public void AddCharacter(char character) | ||
{ | ||
_content.Append(character); | ||
} | ||
|
||
public void ClearToken() | ||
{ | ||
_content.Clear(); | ||
IsElement = false; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System; | ||
|
||
namespace QFXparser.Core | ||
{ | ||
internal class NodeNameAttribute : Attribute | ||
{ | ||
private string _openTag; | ||
private string _closeTag; | ||
|
||
public NodeNameAttribute(string openTag, string closeTag = "") | ||
{ | ||
_openTag = openTag; | ||
_closeTag = closeTag; | ||
} | ||
|
||
public string OpenTag | ||
{ | ||
get | ||
{ | ||
return _openTag; | ||
} | ||
} | ||
|
||
public string CloseTag | ||
{ | ||
get | ||
{ | ||
return _closeTag; | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.