This repository contains a single-phase Argos XML parser that identifies DataBlocks (with optional <Data>
content) and Reports (child elements), extracts relevant lines for filtering, and only includes results for DataBlocks whose <Data>
content (minus lines starting with <
/<
) actually matches specified search terms (like "SSN"
).
When an optional third parameter is set to Y
, the parser will also append the original <Data>
lines at the bottom of each matched DataBlock in SearchMatches.txt
. This can help you see the actual SQL or text lines inside <Data>
(even if they start with <
and were skipped in the filtering logic).
- Overview
- Features
- Structure & Flow
- Usage
- Example Search Flow
- Implementation Details
- Mermaid Diagram
- Customization
- License
Argos exports can be quite large and contain nested <Children>
, <DataBlock>
, <Report>
, and more. This solution:
- Parses a top-level
<Children>
element (and recursively any nested<Children>
). - Discovers each
<DataBlock>
and reads its<Data>
content, converting it to lowercase for case-insensitive filtering. - Skips lines that begin with
<
or<
(to avoid false matches in XML tags) when searching for user-provided terms (e.g.,"SSN"
,"SocialSecurity"
). - Associates any
<Report Name="..." />
elements found inside that DataBlock's<Children>
scope with the DataBlock. - Creates a single file called
SearchMatches.txt
that only includes DataBlocks whose<Data>
lines actually reference any of the user’s search terms. Under each DataBlock, it lists the Reports that belong to it. - (New) Allows an optional third parameter (
Y
) to append the original<Data>
lines (which may include SQL) in the final output.
This approach avoids the problem of repeating the same reports for multiple DataBlocks, ensures lines inside XML tags don’t cause false positives, and produces a minimal, succinct final text file highlighting only the relevant results. Now, if you enable the SQL-extraction feature, you can also see the full <Data>
lines for each matched DataBlock.
- Single-phase parse: direct recursion through
<Children>
blocks. - Case-insensitive search: the solution stores
<Data>
text in lowercase. - Skips lines that begin with
<
or<
, preventing tags like<Condition>SSN</Condition>
from matching. - DataBlock name recognized from:
Name="..."
attribute on<DataBlock>
<Name>Sub-element</Name>
if the attribute is missing or says"Main"
.- Fallback to
UnnamedDataBlock_#
if no valid name is found.
- Search any substring. If a line in
<Data>
contains your search term, that DataBlock is included inSearchMatches.txt
. - Associates
<Report>
elements only if they appear within the same<Children>
scope as the DataBlock. - (New) Optional third parameter (
Y
) → includes the original<Data>
lines (which may contain SQL or other text) at the bottom of each matched DataBlock inSearchMatches.txt
.
The parser’s top-level function:
- Reads the entire Argos export file into memory (
allLines
). - Finds top-level
<Children>
tags and callsParseChildren(...)
. ParseChildren
scans for<DataBlock>
,<Report>
, or nested<Children>
:- If
<DataBlock>
: callsParseDataBlock
to gather<Name>
,<Data>
content. - If
<Report>
: links it to the currentDataBlockNode
(if any).
- If
- Each
DataBlockNode
is stored in a list, eventually processed for matching:- We skip lines starting with
<
when searching. - We do substring checks in lowercase to match search terms like
"SSN"
.
- We skip lines starting with
- Finally, we write out
SearchMatches.txt
for only the matched DataBlocks, with:DataBlock: <name>
Reports:
(child<Report>
names)- If the third parameter is
Y
, aSQL:
section containing the original lines from<Data>
.
- Compile the C# code (for example using
csc ArgosChildrenParser.cs
or a .NET project). - Run the resulting executable:
or omit the third argument if you don’t want to see the
ArgosChildrenParser.exe MyArgosExport.xml "SSN,SocialSecurity" Y
<Data>
lines:ArgosChildrenParser.exe MyArgosExport.xml "SSN,SocialSecurity"
- First: Path to the Argos XML export file.
- Second: Comma-separated search terms. If omitted or empty, all DataBlocks match.
- Third: Optional, if set to
Y
(case-insensitive), the parser appends SQL /<Data>
lines inSearchMatches.txt
.
Consider an Argos export snippet like this:
<Children>
<DataBlock Name="Main">
<Name>Employee Deductions</Name>
<Data>
SELECT ... from EMPLOYEE_TABLE
SSN_Details some text
<Condition>Ignore me</Condition>
</Data>
<Children>
<Report Name="EmpDedReport" />
<Report Name="AnotherReport" />
</Children>
</DataBlock>
</Children>
- The code sees
<DataBlock>
→Name="Main"
but also sees<Name>Employee Deductions</Name>
, so it sets the block’s name to"Employee Deductions"
(overridingMain
). - Reads all lines within
<Data>
into lowercase for searching:- Lines that begin with
<
or<
(like<Condition>Ignore me</Condition>
) are skipped in the search logic. - The line containing
"SSN_Details some text"
is not skipped and thus can match"ssn"
or"SSN"
.
- Lines that begin with
<Report Name="EmpDedReport" />
is linked to this DataBlock.- If
ssn
is part of the search, the line with"SSN_Details"
triggers a match. - If the third parameter is
Y
, the finalSearchMatches.txt
includes:
DataBlock: Employee Deductions
Reports:
- EmpDedReport
- AnotherReport
SQL:
SELECT ... from EMPLOYEE_TABLE
SSN_Details some text
<Condition>Ignore me</Condition>
Otherwise, without Y
, you’ll see the same block + reports but no SQL:
section.
- Recursively processes
<Children>...</Children>
blocks. - Within each
<Children>
block, it can see<DataBlock>
,<Report>
, or nested<Children>
. <DataBlock>
triggers a call toParseDataBlock
to read its content.<Report>
is attached to the currentDataBlockNode
if we’re inside that block’s<Children>
.
- Reads potential
Name="..."
from the<DataBlock ...>
line. - Checks for
<Name>...</Name>
sub-element to override ifName
saysMain
or is empty. - Captures all original
<Data>
lines in aList<string> OriginalDataLines
, plus a lowercased version (BlockDataLower
) for searching.
- Reads lines until
</Report>
is found. - If the
<Report ...>
has aName="..."
attribute, we store it. Otherwise(Unnamed Report)
.
- Splits
BlockDataLower
by lines. - For each line:
- If it starts with
<
or<
, skip it. - Else, check if it contains any user-provided term (also lowercased).
- If it starts with
- Returns
true
on the first match,false
if no match is found.
-
When the user passes
Y
(case-insensitive) as the third argument, we print:SQL: [Line1 from <Data>] [Line2 from <Data>] ...
after the “Reports” block for each matched DataBlock.
flowchart TB
A[Start / main] --> B[Read allLines from Argos XML]
B --> C{Line: <Children>?}
C -- yes --> D[DOUBLECIRCLEEND]
C -- no --> E[skip index++]
D --> F[Store DataBlocks in memory]
F --> G[More lines?]
G -- yes --> C
G -- no --> H[(All DataBlocks Collected)]
H --> I[For each DataBlock => run MatchesSearch on <Data>]
I --> J{Match Found?}
J -- yes --> K[Add DataBlock + Reports to SearchMatches.txt]
J -- no --> L[Skip]
K --> M{3rd param=Y?}
M -- yes --> N[Append original <Data> lines to output]
M -- no --> O[No extra lines]
N --> P[Done for that block]
O --> P[Done for that block]
P --> I
I -->|Done| Q[Finish => SearchMatches.txt]
Explanation:
- We scan lines for
<Children>
, callingParseChildren
recursively. - Collect each
<DataBlock>
into memory with name +<Data>
lines. - Search each block’s
<Data>
content (skipping<...>
lines) for any user terms. - If found, we add to
SearchMatches.txt
.- If the user specified a third param =
Y
, we also append the original<Data>
lines.
- If the user specified a third param =
- Line Skipping: If you also want to skip comment lines or
--
,/*
, etc., adapt the logic inMatchesSearch
. - Case Sensitivity: Currently we do partial substring matching in lowercase. If you need exact boundary matching (
\bSSN\b
), consider a regex approach. - Output Format: If you’d prefer to produce JSON, CSV, or something else instead of
SearchMatches.txt
, you can adjust the final writing logic. - SQL Extraction: This new feature is optional. If a user omits the third argument or sets it to something other than
"Y"
, no<Data>
lines appear inSearchMatches.txt
.
Include a license statement here if desired (e.g., MIT, Apache 2.0):
MIT License
Copyright ...
Permission is hereby granted ...
Enjoy your Argos data-block parsing and searching! For any issues or enhancements, feel free to open a pull request or file an issue in this repository.