BODtoJSON 0.0.6__tar.gz → 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bodtojson-1.0.0/LICENSE +21 -0
- bodtojson-1.0.0/PKG-INFO +113 -0
- bodtojson-1.0.0/README.md +97 -0
- bodtojson-1.0.0/pyproject.toml +25 -0
- bodtojson-1.0.0/setup.cfg +4 -0
- bodtojson-1.0.0/src/BODtoJSON/__init__.py +10 -0
- bodtojson-1.0.0/src/BODtoJSON/mapper.py +56 -0
- bodtojson-1.0.0/src/BODtoJSON.egg-info/PKG-INFO +113 -0
- bodtojson-1.0.0/src/BODtoJSON.egg-info/SOURCES.txt +11 -0
- bodtojson-1.0.0/tests/test_mapper.py +28 -0
- BODtoJSON-0.0.6/BODtoJSON/BODtoJSON.py +0 -106
- BODtoJSON-0.0.6/BODtoJSON/__init_.py +0 -1
- BODtoJSON-0.0.6/BODtoJSON.egg-info/PKG-INFO +0 -38
- BODtoJSON-0.0.6/BODtoJSON.egg-info/SOURCES.txt +0 -10
- BODtoJSON-0.0.6/PKG-INFO +0 -38
- BODtoJSON-0.0.6/README.md +0 -24
- BODtoJSON-0.0.6/setup.cfg +0 -7
- BODtoJSON-0.0.6/setup.py +0 -25
- {BODtoJSON-0.0.6 → bodtojson-1.0.0/src}/BODtoJSON.egg-info/dependency_links.txt +0 -0
- {BODtoJSON-0.0.6 → bodtojson-1.0.0/src}/BODtoJSON.egg-info/requires.txt +0 -0
- {BODtoJSON-0.0.6 → bodtojson-1.0.0/src}/BODtoJSON.egg-info/top_level.txt +0 -0
bodtojson-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Niraj Kakodkar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
bodtojson-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: BODtoJSON
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Production-grade Infor OAGIS BOD to Flattened JSON converter.
|
|
5
|
+
Author: Niraj Kakodkar
|
|
6
|
+
Project-URL: Homepage, https://github.com/thekakodkar/BODtoJSON
|
|
7
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
8
|
+
Classifier: Intended Audience :: Information Technology
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: xmltodict
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# BODtoJSON v1.0.0
|
|
18
|
+
|
|
19
|
+
**BODtoJSON** is an enterprise-grade Python library designed to transform complex Infor OAGIS (XML) Business Object Documents into modern, AI-ready flattened JSON structures.
|
|
20
|
+
|
|
21
|
+
v1.0.0 represents a significant leap from the 0.0.x series, moving from a utility script to a stable, commercialized data asset.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🚀 What’s New in v1.0.0 (vs. v0.0.7)
|
|
26
|
+
|
|
27
|
+
The transition from v0.0.7 to v1.0.0 is more than a version bump; it is a complete architectural refactor:
|
|
28
|
+
|
|
29
|
+
* **`src/` Layout Adoption:** Migrated from a flat directory to the professional `src/` layout.
|
|
30
|
+
* **Strategic Verb Stripping:** Unlike v0.0.7, which often included administrative noise, v1.0.0 intelligently isolates the **Noun** (e.g., `PurchaseOrder`) and removes the **Verb** (e.g., `Sync`). This creates a cleaner dataset for LLM ingestion.
|
|
31
|
+
* **Defensive XML Engine:** * **Namespace Neutralization:** v1.0.0 uses dynamic regex to strip primary namespaces automatically.
|
|
32
|
+
* **BOM Handling:** Added support for UTF-8 Byte Order Marks to prevent "Invalid Token" errors common in ERP exports.
|
|
33
|
+
* **Consolidated API:** The interface has been simplified. You no longer need to navigate deep submodules; simply use `from BODtoJSON import convert`.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 📈 Why it is Better & Improved
|
|
38
|
+
|
|
39
|
+
| Feature | Legacy (v0.0.7) | **Production (v1.0.0)** |
|
|
40
|
+
| :--- | :--- | :--- |
|
|
41
|
+
| **Data Integrity** | Basic key-value mapping | **Preserves Attributes (`_@`) and Values (`_#text`)** |
|
|
42
|
+
| **AI Readiness** | Nested dictionaries (hard to index) | **Fully Flattened (Perfect for Vector DBs)** |
|
|
43
|
+
| **Stability** | Prone to XML namespace errors | **Resilient to OAGIS schema variations** |
|
|
44
|
+
| **Deployment** | Manual script copying | **Standardized Wheel/Source distribution** |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 🛠️ Installation
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install BODtoJSON
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 📂 Project Structure
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
BODtoJSON/
|
|
60
|
+
├── src/
|
|
61
|
+
│ └── BODtoJSON/
|
|
62
|
+
│ ├── __init__.py # Version & API exposure
|
|
63
|
+
│ └── mapper.py # Core Transformation Engine
|
|
64
|
+
├── tests/
|
|
65
|
+
│ ├── config.py # OAGIS XML Test Samples
|
|
66
|
+
│ └── test_mapper.py # Automated Unit Tests (unittest)
|
|
67
|
+
├── scripts/
|
|
68
|
+
│ └── inspect_payload.py # Manual Business Validation Utility
|
|
69
|
+
├── pyproject.toml # Modern Build Configuration
|
|
70
|
+
└── README.md
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 🧪 Validation & Testing
|
|
76
|
+
|
|
77
|
+
### 1. Automated Testing (QA)
|
|
78
|
+
To run the standardized test suite and verify engine logic:
|
|
79
|
+
```powershell
|
|
80
|
+
python -m unittest discover tests
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 2. Manual Payload Inspection (UAT)
|
|
84
|
+
To verify the commercial value of the output and inspect the flattened JSON:
|
|
85
|
+
```powershell
|
|
86
|
+
python scripts/inspect_payload.py
|
|
87
|
+
```
|
|
88
|
+
This script generates an `inspection_result.json` in the root directory for side-by-side audit with the original XML.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 💻 Code Example
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from BODtoJSON import convert
|
|
96
|
+
|
|
97
|
+
# Sample OAGIS XML
|
|
98
|
+
xml_input = """<SyncPurchaseOrder>...</SyncPurchaseOrder>"""
|
|
99
|
+
|
|
100
|
+
# High-fidelity conversion
|
|
101
|
+
# Strips 'Sync' verb, flattens 'PurchaseOrder' noun
|
|
102
|
+
flattened_json = convert(xml_input, verb="Sync")
|
|
103
|
+
|
|
104
|
+
print(flattened_json)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 🤝 Commercial Value
|
|
110
|
+
By normalizing complex ERP structures into flat, labeled JSON, **BODtoJSON** reduces the engineering overhead of AI data preparation by up to 90%. It is built to be a stable foundation for forward-thinking AI strategies and automated business intelligence.
|
|
111
|
+
|
|
112
|
+
**Author:** Niraj Kakodkar
|
|
113
|
+
**License:** MIT
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# BODtoJSON v1.0.0
|
|
2
|
+
|
|
3
|
+
**BODtoJSON** is an enterprise-grade Python library designed to transform complex Infor OAGIS (XML) Business Object Documents into modern, AI-ready flattened JSON structures.
|
|
4
|
+
|
|
5
|
+
v1.0.0 represents a significant leap from the 0.0.x series, moving from a utility script to a stable, commercialized data asset.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🚀 What’s New in v1.0.0 (vs. v0.0.7)
|
|
10
|
+
|
|
11
|
+
The transition from v0.0.7 to v1.0.0 is more than a version bump; it is a complete architectural refactor:
|
|
12
|
+
|
|
13
|
+
* **`src/` Layout Adoption:** Migrated from a flat directory to the professional `src/` layout.
|
|
14
|
+
* **Strategic Verb Stripping:** Unlike v0.0.7, which often included administrative noise, v1.0.0 intelligently isolates the **Noun** (e.g., `PurchaseOrder`) and removes the **Verb** (e.g., `Sync`). This creates a cleaner dataset for LLM ingestion.
|
|
15
|
+
* **Defensive XML Engine:** * **Namespace Neutralization:** v1.0.0 uses dynamic regex to strip primary namespaces automatically.
|
|
16
|
+
* **BOM Handling:** Added support for UTF-8 Byte Order Marks to prevent "Invalid Token" errors common in ERP exports.
|
|
17
|
+
* **Consolidated API:** The interface has been simplified. You no longer need to navigate deep submodules; simply use `from BODtoJSON import convert`.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 📈 Why it is Better & Improved
|
|
22
|
+
|
|
23
|
+
| Feature | Legacy (v0.0.7) | **Production (v1.0.0)** |
|
|
24
|
+
| :--- | :--- | :--- |
|
|
25
|
+
| **Data Integrity** | Basic key-value mapping | **Preserves Attributes (`_@`) and Values (`_#text`)** |
|
|
26
|
+
| **AI Readiness** | Nested dictionaries (hard to index) | **Fully Flattened (Perfect for Vector DBs)** |
|
|
27
|
+
| **Stability** | Prone to XML namespace errors | **Resilient to OAGIS schema variations** |
|
|
28
|
+
| **Deployment** | Manual script copying | **Standardized Wheel/Source distribution** |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 🛠️ Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install BODtoJSON
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 📂 Project Structure
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
BODtoJSON/
|
|
44
|
+
├── src/
|
|
45
|
+
│ └── BODtoJSON/
|
|
46
|
+
│ ├── __init__.py # Version & API exposure
|
|
47
|
+
│ └── mapper.py # Core Transformation Engine
|
|
48
|
+
├── tests/
|
|
49
|
+
│ ├── config.py # OAGIS XML Test Samples
|
|
50
|
+
│ └── test_mapper.py # Automated Unit Tests (unittest)
|
|
51
|
+
├── scripts/
|
|
52
|
+
│ └── inspect_payload.py # Manual Business Validation Utility
|
|
53
|
+
├── pyproject.toml # Modern Build Configuration
|
|
54
|
+
└── README.md
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 🧪 Validation & Testing
|
|
60
|
+
|
|
61
|
+
### 1. Automated Testing (QA)
|
|
62
|
+
To run the standardized test suite and verify engine logic:
|
|
63
|
+
```powershell
|
|
64
|
+
python -m unittest discover tests
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 2. Manual Payload Inspection (UAT)
|
|
68
|
+
To verify the commercial value of the output and inspect the flattened JSON:
|
|
69
|
+
```powershell
|
|
70
|
+
python scripts/inspect_payload.py
|
|
71
|
+
```
|
|
72
|
+
This script generates an `inspection_result.json` in the root directory for side-by-side audit with the original XML.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## 💻 Code Example
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from BODtoJSON import convert
|
|
80
|
+
|
|
81
|
+
# Sample OAGIS XML
|
|
82
|
+
xml_input = """<SyncPurchaseOrder>...</SyncPurchaseOrder>"""
|
|
83
|
+
|
|
84
|
+
# High-fidelity conversion
|
|
85
|
+
# Strips 'Sync' verb, flattens 'PurchaseOrder' noun
|
|
86
|
+
flattened_json = convert(xml_input, verb="Sync")
|
|
87
|
+
|
|
88
|
+
print(flattened_json)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 🤝 Commercial Value
|
|
94
|
+
By normalizing complex ERP structures into flat, labeled JSON, **BODtoJSON** reduces the engineering overhead of AI data preparation by up to 90%. It is built to be a stable foundation for forward-thinking AI strategies and automated business intelligence.
|
|
95
|
+
|
|
96
|
+
**Author:** Niraj Kakodkar
|
|
97
|
+
**License:** MIT
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "BODtoJSON"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name="Niraj Kakodkar" },
|
|
10
|
+
]
|
|
11
|
+
description = "Production-grade Infor OAGIS BOD to Flattened JSON converter."
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.8"
|
|
14
|
+
dependencies = [
|
|
15
|
+
"xmltodict",
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 5 - Production/Stable",
|
|
19
|
+
"Intended Audience :: Information Technology",
|
|
20
|
+
"License :: OSI Approved :: MIT License",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
"Homepage" = "https://github.com/thekakodkar/BODtoJSON"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import xml.etree.ElementTree as ET
|
|
2
|
+
import xmltodict
|
|
3
|
+
import json
|
|
4
|
+
import re
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
|
|
7
|
+
class BODConverter:
|
|
8
|
+
def __init__(self, pnode: str = 'DataArea', separator: str = '_'):
|
|
9
|
+
self.pnode = pnode
|
|
10
|
+
self.separator = separator
|
|
11
|
+
|
|
12
|
+
def convert(self, bod_xml: str, verb: str) -> str:
|
|
13
|
+
try:
|
|
14
|
+
# Defensive cleaning to handle BOM and namespaces
|
|
15
|
+
clean_xml = bod_xml.strip().encode('utf-8').decode('utf-8-sig')
|
|
16
|
+
sanitized_xml = re.sub(r'\sxmlns(?::\w+)?="[^"]+"', '', clean_xml, count=1)
|
|
17
|
+
|
|
18
|
+
root = ET.fromstring(sanitized_xml)
|
|
19
|
+
data_area = root.find(f".//{self.pnode}")
|
|
20
|
+
|
|
21
|
+
if data_area is None:
|
|
22
|
+
raise ValueError(f"Target node '{self.pnode}' not found.")
|
|
23
|
+
|
|
24
|
+
# Remove administrative Verb (Sync/Process)
|
|
25
|
+
verb_node = data_area.find(verb)
|
|
26
|
+
if verb_node is not None:
|
|
27
|
+
data_area.remove(verb_node)
|
|
28
|
+
|
|
29
|
+
# Extract the Noun (the primary child of DataArea)
|
|
30
|
+
# This prevents wrapping the JSON in a redundant 'DataArea' key
|
|
31
|
+
noun_node = list(data_area)[0]
|
|
32
|
+
xml_fragment = ET.tostring(noun_node, encoding='utf-8').decode('utf-8')
|
|
33
|
+
|
|
34
|
+
raw_dict = xmltodict.parse(xml_fragment)
|
|
35
|
+
return json.dumps(self._flatify(raw_dict))
|
|
36
|
+
|
|
37
|
+
except Exception as e:
|
|
38
|
+
return json.dumps({"status": "error", "message": str(e)})
|
|
39
|
+
|
|
40
|
+
def _flatify(self, obj: Any, prefix: str = "") -> Dict[str, Any]:
|
|
41
|
+
flat_dict = {}
|
|
42
|
+
if isinstance(obj, dict):
|
|
43
|
+
for k, v in obj.items():
|
|
44
|
+
new_key = f"{prefix}{self.separator}{k}" if prefix else k
|
|
45
|
+
flat_dict.update(self._flatify(v, new_key))
|
|
46
|
+
elif isinstance(obj, (list, tuple)):
|
|
47
|
+
for i, v in enumerate(obj):
|
|
48
|
+
new_key = f"{prefix}{self.separator}{i}"
|
|
49
|
+
flat_dict.update(self._flatify(v, new_key))
|
|
50
|
+
else:
|
|
51
|
+
flat_dict[prefix] = obj
|
|
52
|
+
return flat_dict
|
|
53
|
+
|
|
54
|
+
def convert(bod_xml: str, verb: str) -> str:
|
|
55
|
+
"""Primary API for BODtoJSON v1.0.0"""
|
|
56
|
+
return BODConverter().convert(bod_xml, verb)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: BODtoJSON
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Production-grade Infor OAGIS BOD to Flattened JSON converter.
|
|
5
|
+
Author: Niraj Kakodkar
|
|
6
|
+
Project-URL: Homepage, https://github.com/thekakodkar/BODtoJSON
|
|
7
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
8
|
+
Classifier: Intended Audience :: Information Technology
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: xmltodict
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# BODtoJSON v1.0.0
|
|
18
|
+
|
|
19
|
+
**BODtoJSON** is an enterprise-grade Python library designed to transform complex Infor OAGIS (XML) Business Object Documents into modern, AI-ready flattened JSON structures.
|
|
20
|
+
|
|
21
|
+
v1.0.0 represents a significant leap from the 0.0.x series, moving from a utility script to a stable, commercialized data asset.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🚀 What’s New in v1.0.0 (vs. v0.0.7)
|
|
26
|
+
|
|
27
|
+
The transition from v0.0.7 to v1.0.0 is more than a version bump; it is a complete architectural refactor:
|
|
28
|
+
|
|
29
|
+
* **`src/` Layout Adoption:** Migrated from a flat directory to the professional `src/` layout.
|
|
30
|
+
* **Strategic Verb Stripping:** Unlike v0.0.7, which often included administrative noise, v1.0.0 intelligently isolates the **Noun** (e.g., `PurchaseOrder`) and removes the **Verb** (e.g., `Sync`). This creates a cleaner dataset for LLM ingestion.
|
|
31
|
+
* **Defensive XML Engine:** * **Namespace Neutralization:** v1.0.0 uses dynamic regex to strip primary namespaces automatically.
|
|
32
|
+
* **BOM Handling:** Added support for UTF-8 Byte Order Marks to prevent "Invalid Token" errors common in ERP exports.
|
|
33
|
+
* **Consolidated API:** The interface has been simplified. You no longer need to navigate deep submodules; simply use `from BODtoJSON import convert`.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 📈 Why it is Better & Improved
|
|
38
|
+
|
|
39
|
+
| Feature | Legacy (v0.0.7) | **Production (v1.0.0)** |
|
|
40
|
+
| :--- | :--- | :--- |
|
|
41
|
+
| **Data Integrity** | Basic key-value mapping | **Preserves Attributes (`_@`) and Values (`_#text`)** |
|
|
42
|
+
| **AI Readiness** | Nested dictionaries (hard to index) | **Fully Flattened (Perfect for Vector DBs)** |
|
|
43
|
+
| **Stability** | Prone to XML namespace errors | **Resilient to OAGIS schema variations** |
|
|
44
|
+
| **Deployment** | Manual script copying | **Standardized Wheel/Source distribution** |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 🛠️ Installation
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install BODtoJSON
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 📂 Project Structure
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
BODtoJSON/
|
|
60
|
+
├── src/
|
|
61
|
+
│ └── BODtoJSON/
|
|
62
|
+
│ ├── __init__.py # Version & API exposure
|
|
63
|
+
│ └── mapper.py # Core Transformation Engine
|
|
64
|
+
├── tests/
|
|
65
|
+
│ ├── config.py # OAGIS XML Test Samples
|
|
66
|
+
│ └── test_mapper.py # Automated Unit Tests (unittest)
|
|
67
|
+
├── scripts/
|
|
68
|
+
│ └── inspect_payload.py # Manual Business Validation Utility
|
|
69
|
+
├── pyproject.toml # Modern Build Configuration
|
|
70
|
+
└── README.md
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 🧪 Validation & Testing
|
|
76
|
+
|
|
77
|
+
### 1. Automated Testing (QA)
|
|
78
|
+
To run the standardized test suite and verify engine logic:
|
|
79
|
+
```powershell
|
|
80
|
+
python -m unittest discover tests
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 2. Manual Payload Inspection (UAT)
|
|
84
|
+
To verify the commercial value of the output and inspect the flattened JSON:
|
|
85
|
+
```powershell
|
|
86
|
+
python scripts/inspect_payload.py
|
|
87
|
+
```
|
|
88
|
+
This script generates an `inspection_result.json` in the root directory for side-by-side audit with the original XML.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 💻 Code Example
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from BODtoJSON import convert
|
|
96
|
+
|
|
97
|
+
# Sample OAGIS XML
|
|
98
|
+
xml_input = """<SyncPurchaseOrder>...</SyncPurchaseOrder>"""
|
|
99
|
+
|
|
100
|
+
# High-fidelity conversion
|
|
101
|
+
# Strips 'Sync' verb, flattens 'PurchaseOrder' noun
|
|
102
|
+
flattened_json = convert(xml_input, verb="Sync")
|
|
103
|
+
|
|
104
|
+
print(flattened_json)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 🤝 Commercial Value
|
|
110
|
+
By normalizing complex ERP structures into flat, labeled JSON, **BODtoJSON** reduces the engineering overhead of AI data preparation by up to 90%. It is built to be a stable foundation for forward-thinking AI strategies and automated business intelligence.
|
|
111
|
+
|
|
112
|
+
**Author:** Niraj Kakodkar
|
|
113
|
+
**License:** MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/BODtoJSON/__init__.py
|
|
5
|
+
src/BODtoJSON/mapper.py
|
|
6
|
+
src/BODtoJSON.egg-info/PKG-INFO
|
|
7
|
+
src/BODtoJSON.egg-info/SOURCES.txt
|
|
8
|
+
src/BODtoJSON.egg-info/dependency_links.txt
|
|
9
|
+
src/BODtoJSON.egg-info/requires.txt
|
|
10
|
+
src/BODtoJSON.egg-info/top_level.txt
|
|
11
|
+
tests/test_mapper.py
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
import json
|
|
3
|
+
import sys
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
# Align pathing for local testing
|
|
7
|
+
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../src')))
|
|
8
|
+
|
|
9
|
+
from BODtoJSON import convert
|
|
10
|
+
from config import Config
|
|
11
|
+
|
|
12
|
+
class TestBODtoJSON(unittest.TestCase):
|
|
13
|
+
def test_sync_purchase_order(self):
|
|
14
|
+
result_json = convert(Config.INPUT_VAR, "Sync")
|
|
15
|
+
data = json.loads(result_json)
|
|
16
|
+
|
|
17
|
+
# ALIGNED KEY: Engine includes the Noun name (PurchaseOrder)
|
|
18
|
+
expected_key = "PurchaseOrder_PurchaseOrderHeader_DocumentID_ID_#text"
|
|
19
|
+
|
|
20
|
+
# Verification
|
|
21
|
+
self.assertEqual(
|
|
22
|
+
data.get(expected_key),
|
|
23
|
+
"PSU000049",
|
|
24
|
+
f"Key mismatch. Available keys: {list(data.keys())}"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if __name__ == "__main__":
|
|
28
|
+
unittest.main()
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2020 Niraj Kakodkar
|
|
2
|
-
#
|
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
-
# furnished to do so, subject to the following conditions:
|
|
9
|
-
#
|
|
10
|
-
# The above copyright notice and this permission notice shall be included in all
|
|
11
|
-
# copies or substantial portions of the Software.
|
|
12
|
-
#
|
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
-
# SOFTWARE.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
import xmltodict, json
|
|
23
|
-
import xml.etree.ElementTree as ET
|
|
24
|
-
import re
|
|
25
|
-
pnode = 'DataArea'
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def convert(bod, noun):
|
|
29
|
-
"""
|
|
30
|
-
converts the input BOX XML to Flat JASON
|
|
31
|
-
:param bod:
|
|
32
|
-
:return: Flat JSON
|
|
33
|
-
"""
|
|
34
|
-
# Remove Namespaces from XML
|
|
35
|
-
input = re.sub(' xmlns="[^"]+"', '', bod, count=1)
|
|
36
|
-
|
|
37
|
-
# Create an Element Tree
|
|
38
|
-
root = ET.fromstring(input)
|
|
39
|
-
|
|
40
|
-
# Extract the Data Area
|
|
41
|
-
# Remove unnecessary Nodes
|
|
42
|
-
for parentnode in root.findall(pnode):
|
|
43
|
-
for node in parentnode.findall(noun):
|
|
44
|
-
parentnode.remove(node)
|
|
45
|
-
root = ET.tostring(parentnode).decode('utf-8')
|
|
46
|
-
|
|
47
|
-
jsonout = xmltodict.parse(root)
|
|
48
|
-
jsonout = flatify(jsonout)
|
|
49
|
-
jsonout = json.dumps(jsonout)
|
|
50
|
-
return (jsonout)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def _genkey(prev_key, separator, new_key):
|
|
54
|
-
"""
|
|
55
|
-
Returns the new_key in case no prev key exists, concatenates
|
|
56
|
-
prev key, separator, and new_key otherwise
|
|
57
|
-
:param prev_key:
|
|
58
|
-
:param separator:
|
|
59
|
-
:param new_key:
|
|
60
|
-
:return: a string if prev_key exists and simply passes through the
|
|
61
|
-
new_key otherwise
|
|
62
|
-
"""
|
|
63
|
-
if prev_key:
|
|
64
|
-
return u"{}{}{}".format(prev_key, separator, new_key)
|
|
65
|
-
else:
|
|
66
|
-
return new_key
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def flatify(idict, separator="_", root_keys_to_ignore=set()):
|
|
70
|
-
"""
|
|
71
|
-
Creates flat dictionary from the nested dictionary
|
|
72
|
-
|
|
73
|
-
:param idict: Nested dictionary we want to make flat
|
|
74
|
-
:param separator: string to separate dictionary keys by
|
|
75
|
-
:param root_keys_to_ignore: set of root keys to ignore from flattening
|
|
76
|
-
:return: flat dictionary
|
|
77
|
-
"""
|
|
78
|
-
assert isinstance(idict, dict), "flattify requires a dictionary input"
|
|
79
|
-
assert isinstance(separator, str), "separator must be string"
|
|
80
|
-
|
|
81
|
-
flat_dict = dict()
|
|
82
|
-
|
|
83
|
-
def _flatify(object_, key):
|
|
84
|
-
"""
|
|
85
|
-
:param object_: object to flatten
|
|
86
|
-
:param key: carries the concatenated key for the object_
|
|
87
|
-
:return: None
|
|
88
|
-
"""
|
|
89
|
-
# Empty object can't be iterated, take as is
|
|
90
|
-
if not object_:
|
|
91
|
-
flat_dict[key] = object_
|
|
92
|
-
# These object types support iteration
|
|
93
|
-
elif isinstance(object_, dict):
|
|
94
|
-
for object_key in object_:
|
|
95
|
-
if not (not key and object_key in root_keys_to_ignore):
|
|
96
|
-
_flatify(object_[object_key], _genkey(key,
|
|
97
|
-
separator,
|
|
98
|
-
object_key))
|
|
99
|
-
elif isinstance(object_, (list, set, tuple)):
|
|
100
|
-
for index, item in enumerate(object_):
|
|
101
|
-
_flatify(item, _genkey(key, separator, index))
|
|
102
|
-
else:
|
|
103
|
-
flat_dict[key] = object_
|
|
104
|
-
|
|
105
|
-
_flatify(idict, None)
|
|
106
|
-
return flat_dict
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from BODtoJSON.BODtoJSON import convert
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: BODtoJSON
|
|
3
|
-
Version: 0.0.6
|
|
4
|
-
Summary: Converts Infor QAGIS BODs to flattened JSON
|
|
5
|
-
Home-page: https://github.com/thekakodkar/Mapper
|
|
6
|
-
Author: Niraj Kakodkar
|
|
7
|
-
Author-email: niraj.kakodkar@gmail.com
|
|
8
|
-
License: MIT
|
|
9
|
-
Description: # Mapper
|
|
10
|
-
|
|
11
|
-
Mapper is a python library to convert the Infor OAGIS BODs to Flattened JSON.
|
|
12
|
-
The library simplifies the converted JSON by keeping only the content within DataArea.
|
|
13
|
-
The library will remove the Verb node from DataArea and keeps only the Noun node.
|
|
14
|
-
|
|
15
|
-
#### Usage
|
|
16
|
-
|
|
17
|
-
##### Getting it
|
|
18
|
-
To download BODtoJSON, either fork this github repo or simply use Pypi via pip.
|
|
19
|
-
```python
|
|
20
|
-
$ pip install BODtoJSON==0.0.6
|
|
21
|
-
```
|
|
22
|
-
##### Using it:
|
|
23
|
-
```python
|
|
24
|
-
from BODtoJSON.BODtoJSON import convert
|
|
25
|
-
output_var = convert(bodxml, noun)
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
#### MIT License
|
|
29
|
-
Read License.txt
|
|
30
|
-
|
|
31
|
-
#### GITHUB
|
|
32
|
-
Fork me on github https://github.com/thekakodkar/Mapper
|
|
33
|
-
Platform: UNKNOWN
|
|
34
|
-
Classifier: Programming Language :: Python :: 3
|
|
35
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
36
|
-
Classifier: Operating System :: OS Independent
|
|
37
|
-
Requires-Python: >=3.0
|
|
38
|
-
Description-Content-Type: text/markdown
|
BODtoJSON-0.0.6/PKG-INFO
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: BODtoJSON
|
|
3
|
-
Version: 0.0.6
|
|
4
|
-
Summary: Converts Infor QAGIS BODs to flattened JSON
|
|
5
|
-
Home-page: https://github.com/thekakodkar/Mapper
|
|
6
|
-
Author: Niraj Kakodkar
|
|
7
|
-
Author-email: niraj.kakodkar@gmail.com
|
|
8
|
-
License: MIT
|
|
9
|
-
Description: # Mapper
|
|
10
|
-
|
|
11
|
-
Mapper is a python library to convert the Infor OAGIS BODs to Flattened JSON.
|
|
12
|
-
The library simplifies the converted JSON by keeping only the content within DataArea.
|
|
13
|
-
The library will remove the Verb node from DataArea and keeps only the Noun node.
|
|
14
|
-
|
|
15
|
-
#### Usage
|
|
16
|
-
|
|
17
|
-
##### Getting it
|
|
18
|
-
To download BODtoJSON, either fork this github repo or simply use Pypi via pip.
|
|
19
|
-
```python
|
|
20
|
-
$ pip install BODtoJSON==0.0.6
|
|
21
|
-
```
|
|
22
|
-
##### Using it:
|
|
23
|
-
```python
|
|
24
|
-
from BODtoJSON.BODtoJSON import convert
|
|
25
|
-
output_var = convert(bodxml, noun)
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
#### MIT License
|
|
29
|
-
Read License.txt
|
|
30
|
-
|
|
31
|
-
#### GITHUB
|
|
32
|
-
Fork me on github https://github.com/thekakodkar/Mapper
|
|
33
|
-
Platform: UNKNOWN
|
|
34
|
-
Classifier: Programming Language :: Python :: 3
|
|
35
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
36
|
-
Classifier: Operating System :: OS Independent
|
|
37
|
-
Requires-Python: >=3.0
|
|
38
|
-
Description-Content-Type: text/markdown
|
BODtoJSON-0.0.6/README.md
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# Mapper
|
|
2
|
-
|
|
3
|
-
Mapper is a python library to convert the Infor OAGIS BODs to Flattened JSON.
|
|
4
|
-
The library simplifies the converted JSON by keeping only the content within DataArea.
|
|
5
|
-
The library will remove the Verb node from DataArea and keeps only the Noun node.
|
|
6
|
-
|
|
7
|
-
#### Usage
|
|
8
|
-
|
|
9
|
-
##### Getting it
|
|
10
|
-
To download BODtoJSON, either fork this github repo or simply use Pypi via pip.
|
|
11
|
-
```python
|
|
12
|
-
$ pip install BODtoJSON==0.0.6
|
|
13
|
-
```
|
|
14
|
-
##### Using it:
|
|
15
|
-
```python
|
|
16
|
-
from BODtoJSON.BODtoJSON import convert
|
|
17
|
-
output_var = convert(bodxml, noun)
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
#### MIT License
|
|
21
|
-
Read License.txt
|
|
22
|
-
|
|
23
|
-
#### GITHUB
|
|
24
|
-
Fork me on github https://github.com/thekakodkar/Mapper
|
BODtoJSON-0.0.6/setup.cfg
DELETED
BODtoJSON-0.0.6/setup.py
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import setuptools
|
|
2
|
-
from setuptools import setup
|
|
3
|
-
|
|
4
|
-
with open("README.md", "r") as fh:
|
|
5
|
-
long_description = fh.read()
|
|
6
|
-
|
|
7
|
-
setup(
|
|
8
|
-
name="BODtoJSON",
|
|
9
|
-
version="0.0.6",
|
|
10
|
-
author="Niraj Kakodkar",
|
|
11
|
-
author_email="niraj.kakodkar@gmail.com",
|
|
12
|
-
license='MIT',
|
|
13
|
-
description="Converts Infor QAGIS BODs to flattened JSON",
|
|
14
|
-
long_description=long_description,
|
|
15
|
-
long_description_content_type="text/markdown",
|
|
16
|
-
url="https://github.com/thekakodkar/Mapper",
|
|
17
|
-
packages=['BODtoJSON'],
|
|
18
|
-
classifiers=[
|
|
19
|
-
"Programming Language :: Python :: 3",
|
|
20
|
-
"License :: OSI Approved :: MIT License",
|
|
21
|
-
"Operating System :: OS Independent",
|
|
22
|
-
],
|
|
23
|
-
install_requires=['xmltodict'],
|
|
24
|
-
python_requires='>=3.0',
|
|
25
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|