Skip to content

Commit 69e88f9

Browse files
committed
add sources
1 parent e8a43f1 commit 69e88f9

24 files changed

Lines changed: 1610 additions & 2 deletions

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
.vs/
2+
vcpkg_installed/
3+
x64/
4+
15
# Prerequisites
26
*.d
37

@@ -39,3 +43,5 @@
3943

4044
# debug information files
4145
*.dwo
46+
47+
*.aps

README.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,21 @@
1-
# simple-xml-validator
2-
lightweight XML Schema validation utility
1+
2+
# Simple Xml Validator
3+
Xsd and Xml Validator
4+
5+
Free lightweight XML Schema validation utility with the following features:
6+
7+
- Check if schema is valid
8+
> Click "Browse" or use drag & drop to open xsd file. Validation will be performed with errors reported in the log view.
9+
[Apache Xerces-C++](https://xerces.apache.org/xerces-c/) is used for validation
10+
- Validate xml files
11+
> Once xsd schema is loaded, click "Browse" again to select xml file for validation against schema loaded.
12+
Note: you can select xml without selecting xsd first, if it contains proper schema reference (schemaLocation attribute).
13+
Validation is fully streaming and xml files of any size can be used.
14+
15+
![screenshot](simpleXmlValidator.png)
16+
17+
## Advantages over online validators:
18+
19+
- Multi-file schema documents can be used
20+
- Can validate files of any size: using SAX parser which is using streaming to process huge xml documents with low memory footprint
21+
- Can validate XSD schema itself (without XML)

SimpleXmlValidator.sln

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 2013
4+
VisualStudioVersion = 12.0.40629.0
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimpleXmlValidator", "SimpleXmlValidator\SimpleXmlValidator.vcxproj", "{F1AE0E15-54ED-4818-A0DA-0FAAC2D10A2A}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Win32 = Debug|Win32
11+
Debug|x64 = Debug|x64
12+
Release|Win32 = Release|Win32
13+
Release|x64 = Release|x64
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{F1AE0E15-54ED-4818-A0DA-0FAAC2D10A2A}.Debug|Win32.ActiveCfg = Debug|Win32
17+
{F1AE0E15-54ED-4818-A0DA-0FAAC2D10A2A}.Debug|Win32.Build.0 = Debug|Win32
18+
{F1AE0E15-54ED-4818-A0DA-0FAAC2D10A2A}.Debug|x64.ActiveCfg = Debug|x64
19+
{F1AE0E15-54ED-4818-A0DA-0FAAC2D10A2A}.Debug|x64.Build.0 = Debug|x64
20+
{F1AE0E15-54ED-4818-A0DA-0FAAC2D10A2A}.Release|Win32.ActiveCfg = Release|Win32
21+
{F1AE0E15-54ED-4818-A0DA-0FAAC2D10A2A}.Release|Win32.Build.0 = Release|Win32
22+
{F1AE0E15-54ED-4818-A0DA-0FAAC2D10A2A}.Release|x64.ActiveCfg = Release|x64
23+
{F1AE0E15-54ED-4818-A0DA-0FAAC2D10A2A}.Release|x64.Build.0 = Release|x64
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
EndGlobal

SimpleXmlValidator/AboutDlg.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// aboutdlg.cpp : implementation of the CAboutDlg class
2+
//
3+
/////////////////////////////////////////////////////////////////////////////
4+
5+
#include "stdafx.h"
6+
#include "resource.h"
7+
8+
#include "aboutdlg.h"
9+
10+
LRESULT CAboutDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
11+
{
12+
CenterWindow(GetParent());
13+
return TRUE;
14+
}
15+
16+
LRESULT CAboutDlg::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
17+
{
18+
EndDialog(wID);
19+
return 0;
20+
}
21+
22+
23+
LRESULT CAboutDlg::OnNMClickSyslink2(int /*idCtrl*/, LPNMHDR pNMHDR, BOOL& /*bHandled*/)
24+
{
25+
ShellExecuteW(NULL, L"open", L"mailto:tadamovsky@gmail.com", NULL, NULL, SW_SHOWNORMAL);
26+
return 0;
27+
}
28+
29+
LRESULT CAboutDlg::OnNMClickSyslink1(int /*idCtrl*/, LPNMHDR pNMHDR, BOOL& /*bHandled*/)
30+
{
31+
ShellExecuteW(NULL, L"open", L"https://github.com/tadamovsky/simple-xml-validator", NULL, NULL, SW_SHOWNORMAL);
32+
return 0;
33+
}

SimpleXmlValidator/AboutDlg.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// aboutdlg.h : interface of the CAboutDlg class
2+
//
3+
/////////////////////////////////////////////////////////////////////////////
4+
5+
#pragma once
6+
7+
class CAboutDlg : public CDialogImpl<CAboutDlg>
8+
{
9+
public:
10+
enum { IDD = IDD_ABOUTBOX };
11+
12+
BEGIN_MSG_MAP(CAboutDlg)
13+
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
14+
COMMAND_ID_HANDLER(IDOK, OnCloseCmd)
15+
COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)
16+
NOTIFY_HANDLER(IDC_SYSLINK1, NM_CLICK, OnNMClickSyslink1)
17+
NOTIFY_HANDLER(IDC_SYSLINK2, NM_CLICK, OnNMClickSyslink2)
18+
END_MSG_MAP()
19+
20+
// Handler prototypes (uncomment arguments if needed):
21+
// LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
22+
// LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
23+
// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
24+
25+
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
26+
LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
27+
LRESULT OnNMClickSyslink1(int /*idCtrl*/, LPNMHDR pNMHDR, BOOL& /*bHandled*/);
28+
LRESULT OnNMClickSyslink2(int /*idCtrl*/, LPNMHDR pNMHDR, BOOL& /*bHandled*/);
29+
};

SimpleXmlValidator/MainDlg.cpp

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
// MainDlg.cpp : implementation of the CMainDlg class
2+
//
3+
/////////////////////////////////////////////////////////////////////////////
4+
5+
#include "stdafx.h"
6+
#include "resource.h"
7+
#include "PParseHandlers.hpp"
8+
#include "XercesVal.h"
9+
#include "aboutdlg.h"
10+
#include "MainDlg.h"
11+
12+
static bool isXsdFilePath(const wchar_t* path) {
13+
const wchar_t* ext = wcsrchr(path, '.');
14+
return ext && wcscmp(ext + 1, L"xsd") == 0;
15+
}
16+
17+
BOOL CMainDlg::PreTranslateMessage(MSG* pMsg)
18+
{
19+
if (pMsg->message == WM_LBUTTONDBLCLK &&
20+
pMsg->hwnd == ::GetDlgItem(m_hWnd, IDC_EDIT1))
21+
{
22+
CEdit editBox(GetDlgItem(IDC_EDIT1));
23+
CAtlString basestr;
24+
CSimpleStringW str(basestr.GetManager());
25+
editBox.GetWindowTextW(str);
26+
if (str.GetLength() > 0 && OpenClipboard())
27+
{
28+
int len = (str.GetLength() + 1) * sizeof(str[0]);
29+
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, len);
30+
LPVOID lpText = NULL;
31+
if (hGlobal != NULL)
32+
lpText = GlobalLock(hGlobal);
33+
if (lpText != NULL)
34+
{
35+
memcpy(lpText, str.GetBuffer(), len);
36+
EmptyClipboard();
37+
GlobalUnlock(hGlobal);
38+
SetClipboardData(CF_UNICODETEXT, hGlobal);
39+
}
40+
CloseClipboard();
41+
::MessageBoxW(m_hWnd, _T("Text copied."), L"Copy to clipboard", MB_OK);
42+
}
43+
44+
return TRUE; //Important!!! Message is handled
45+
}
46+
return CWindow::IsDialogMessage(pMsg);
47+
}
48+
49+
BOOL CMainDlg::OnIdle()
50+
{
51+
UIUpdateChildWindows();
52+
return FALSE;
53+
}
54+
55+
LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
56+
{
57+
// center the dialog on the screen
58+
CenterWindow();
59+
60+
// set icons
61+
HICON hIcon = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));
62+
SetIcon(hIcon, TRUE);
63+
HICON hIconSmall = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON));
64+
SetIcon(hIconSmall, FALSE);
65+
66+
// register object for message filtering and idle updates
67+
CMessageLoop* pLoop = _Module.GetMessageLoop();
68+
ATLASSERT(pLoop != NULL);
69+
pLoop->AddMessageFilter(this);
70+
pLoop->AddIdleHandler(this);
71+
72+
UIAddChildWindowContainer(m_hWnd);
73+
InitDynamicLayout(false);
74+
75+
validator.reset(new XercesValidator);
76+
xmlState = eLoadedState::NO;
77+
xsdState = eLoadedState::NO;
78+
79+
if (const int argc = __argc; argc > 1) {
80+
CStringW xsdPath;
81+
CStringW xmlPath;
82+
for (int i = 1; i < argc; ++i) {
83+
const wchar_t* path = __wargv[i];
84+
if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(path)) {
85+
::MessageBoxW(m_hWnd, path, L"File not found!", MB_OK | MB_ICONERROR);
86+
break;
87+
}
88+
if (isXsdFilePath(path))
89+
xsdPath = path;
90+
else
91+
xmlPath = path;
92+
}
93+
if (!xsdPath.IsEmpty())
94+
validateFile(xsdPath);
95+
if (!xmlPath.IsEmpty())
96+
validateFile(xmlPath);
97+
}
98+
99+
return TRUE;
100+
}
101+
102+
LRESULT CMainDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
103+
{
104+
// unregister message filtering and idle updates
105+
CMessageLoop* pLoop = _Module.GetMessageLoop();
106+
ATLASSERT(pLoop != NULL);
107+
pLoop->RemoveMessageFilter(this);
108+
pLoop->RemoveIdleHandler(this);
109+
110+
return 0;
111+
}
112+
113+
LRESULT CMainDlg::OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
114+
{
115+
CAboutDlg dlg;
116+
dlg.DoModal();
117+
return 0;
118+
}
119+
120+
LRESULT CMainDlg::OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
121+
{
122+
CSimpleFileDialog fileDialog(TRUE,
123+
NULL,
124+
NULL,
125+
OFN_HIDEREADONLY,
126+
L"XML Files (*.xsd;*.xml)\0*.xsd;*.xml\00");
127+
128+
if (fileDialog.DoModal() == IDOK)
129+
{
130+
validateFile(fileDialog.m_szFileName);
131+
} return 0;
132+
}
133+
134+
LRESULT CMainDlg::OnDropFile(HDROP hDropInfo)
135+
{
136+
TCHAR path[MAX_PATH] = { 0 };
137+
CStringW xsdPath;
138+
CStringW xmlPath;
139+
140+
UINT uFile = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, NULL);
141+
if (uFile != 0) {
142+
for (UINT i = 0; i < uFile; i++) {
143+
path[0] = '\0';
144+
if (DragQueryFile(hDropInfo, i, path, MAX_PATH)) {
145+
if (isXsdFilePath(path))
146+
xsdPath = path;
147+
else
148+
xmlPath = path;
149+
}
150+
}
151+
}
152+
DragFinish(hDropInfo);
153+
if (!xsdPath.IsEmpty())
154+
validateFile(xsdPath);
155+
if (!xmlPath.IsEmpty())
156+
validateFile(xmlPath);
157+
return 0;
158+
}
159+
160+
void CMainDlg::validateFile(const wchar_t* path)
161+
{
162+
bool isXsdFile = isXsdFilePath(path);
163+
std::wstringstream errors;
164+
bool success = isXsdFile ? validator->setAndValidateXsd(path, errors) : validator->setAndValidateXml(path, errors);
165+
CStatic xsdBox(GetDlgItem(IDC_XSD));
166+
CStatic xmlBox(GetDlgItem(IDC_XML));
167+
168+
if (isXsdFile) {
169+
xsdState = success ? eLoadedState::YES : eLoadedState::INVALID;
170+
xsdBox.SetWindowTextW(success ? L"VALID" : L"INVALID");
171+
172+
xmlState = eLoadedState::NO;
173+
xmlBox.SetWindowTextW(L"");
174+
}
175+
else {
176+
if (xsdState == eLoadedState::INVALID) {
177+
xsdState = eLoadedState::NO;
178+
xsdBox.SetWindowTextW(L"");
179+
}
180+
xmlState = success ? eLoadedState::YES : eLoadedState::INVALID;
181+
xmlBox.SetWindowTextW(success ? L"VALID" : L"INVALID");
182+
}
183+
updateFileLables(path, isXsdFile);
184+
CEdit editBox(GetDlgItem(IDC_EDIT1));
185+
editBox.SetWindowTextW(success ? L"" : errors.str().c_str());
186+
}
187+
188+
void CMainDlg::updateFileLables(const wchar_t* _path, bool isXsd)
189+
{
190+
const wchar_t* sep = wcsrchr(_path, '\\');
191+
const wchar_t* path = sep ? sep + 1 : _path;
192+
CStatic xsdBox(GetDlgItem(IDC_XSD_SELECTED));
193+
CStatic xmlBox(GetDlgItem(IDC_XML_SELECTED));
194+
195+
std::wstring s;
196+
if (isXsd) {
197+
s = L"XSD file selected: ";
198+
s += path;
199+
xsdBox.SetWindowTextW(s.c_str());
200+
xmlBox.SetWindowTextW(L"XML file selected: NONE");
201+
}
202+
else {
203+
if (xsdState == eLoadedState::NO) {
204+
xsdBox.SetWindowTextW(L"XSD file selected: NONE");
205+
}
206+
s = L"XML file selected: ";
207+
s += path;
208+
xmlBox.SetWindowTextW(s.c_str());
209+
}
210+
}
211+
212+
213+
LRESULT CMainDlg::OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
214+
{
215+
CloseDialog(wID);
216+
return 0;
217+
}
218+
219+
void CMainDlg::CloseDialog(int nVal)
220+
{
221+
DestroyWindow();
222+
::PostQuitMessage(nVal);
223+
}
224+
225+
LRESULT CMainDlg::OnStaticCtlColor(HDC hdcStatic, HWND hwnd)
226+
{
227+
static HBRUSH greenBrush(CreateSolidBrush(RGB(0, 255, 0)));
228+
static HBRUSH redBrush(CreateSolidBrush(RGB(255, 0, 0)));
229+
230+
if (GetDlgItem(IDC_XSD).m_hWnd == hwnd && xsdState != eLoadedState::NO) {
231+
//::SetTextColor(hdcStatic, RGB(0, 0, 0));
232+
//::SetBkColor(hdcStatic, RGB(0, 255, 0));
233+
::SetBkMode(hdcStatic, TRANSPARENT);
234+
::SelectObject(hdcStatic, xsdState == eLoadedState::YES ? greenBrush : redBrush);
235+
return (LRESULT)::GetCurrentObject(hdcStatic, OBJ_BRUSH);
236+
}
237+
else if (GetDlgItem(IDC_XML).m_hWnd == hwnd && xmlState != eLoadedState::NO) {
238+
::SetBkMode(hdcStatic, TRANSPARENT);
239+
::SelectObject(hdcStatic, xmlState == eLoadedState::YES ? greenBrush : redBrush);
240+
return (LRESULT)::GetCurrentObject(hdcStatic, OBJ_BRUSH);
241+
}
242+
else {
243+
this->SetMsgHandled(FALSE);
244+
return 0;
245+
}
246+
}

0 commit comments

Comments
 (0)