XML Transform Builder
A package of transfoming XML files using XSLT transformations. The package is designed to take JSON configuration files and generate XSLT transformations based on the operations specified in the JSON.
The generated XSLT can then be used to transform XML files according to the specified changes.
Features
- Generate XSLT transformations using a clean, fluent API
- Support for adding, renaming, and removing XML elements and attributes
- Version updating
- Process transformations from JSON configuration files
Usage
Load configuration
string json = File.ReadAllText("config.json");
var transformService = new TransformationService();
Generate XSLT
string xslt = transformService.GenerateXslt(json);
Save or apply the transformation File.WriteAllText("transform.xslt", xslt);
JSON Configuration Format
{
"Operations": {
"Add": {
"Elements": {
"Site": {
"CustomProperties": {
"_attributes": {},
"Entry": {
"_attributes": {
"Name": "intelId",
"Value": "",
"Type": "string"
}
}
}
}
},
"Attributes": {
"Origin": {
"CtreationTime": "2025-03-26"
}
}
}
}
}
What is this code doing?
This code is a tool that converts simple JSON configuration files into XSLT transformations. Think of it as a translator that takes easy-to-write JSON instructions and turns them into specialized XML transformation code.
Essential XSLT Concepts You Need to Know
1. XSLT Basics and Structure
XSLT (Extensible Stylesheet Language Transformations) is an XML-based language for transforming XML documents into other formats. Every XSLT document starts with a root element:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
</xsl:stylesheet>
In the code, this is created by the CreateStylesheet()
method in the XsltBuilder
class.
2. Templates
Templates are the core building blocks of XSLT. Each template uses a "match" attribute with an XPath expression to specify which nodes it applies to:
<xsl:template match="elementName">
</xsl:template>
The code creates templates for each operation using the XsltTemplateBuilder
class.
3. Identity Transform
The identity transform is a standard XSLT pattern that copies everything from input to output unless another template overrides it:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
This is implemented in the AddIdentityTransform()
method and serves as the default behavior.
4. XPath Expressions
XPath is used in the "match" and "select" attributes to identify nodes:
@*
- All attributes
node()
- All nodes (elements, text, comments, etc.)
//*[@Version]
- Any element with a "Version" attribute
@*[name()!='Version']
- All attributes except "Version"
The code uses these XPath patterns throughout the template builders.
5. XSLT Instructions
Key XSLT instructions you'll see in the code:
-
copy: <xsl:copy>
copies the current node without attributes or children
<xsl:copy></xsl:copy>
-
apply-templates: <xsl:apply-templates>
processes child nodes
<xsl:apply-templates select="@*|node()"/>
-
element: <xsl:element>
creates a new element
<xsl:element name="newElement"></xsl:element>
-
attribute: <xsl:attribute>
creates a new attribute
<xsl:attribute name="attrName">value</xsl:attribute>
-
value-of: <xsl:value-of>
extracts values from the source
<xsl:value-of select="@sourceAttribute"/>
6. Common XSLT Patterns
Element Renaming Pattern
<xsl:template match="oldName">
<xsl:element name="newName">
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
</xsl:element>
</xsl:template>
Attribute Addition Pattern
<xsl:template match="targetElement">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="newAttr">value</xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
Node Deletion Pattern
Empty templates delete matching nodes:
<xsl:template match="elementToRemove"/>
7. XSLT Processing Model
XSLT processing is template-driven, not procedural. The processor:
- Starts at the document root
- For each node, finds the most specific matching template
- Applies the template's instructions
- Continues until all nodes are processed
This is why the identity transform is important - it provides a default behavior for nodes that don't match specific templates.
8. Understanding XSLT Namespaces
The XML namespace http://www.w3.org/1999/XSL/Transform
(usually prefixed as xsl:
) is required for all XSLT elements. The code manages this with the _xsl
field:
private readonly XNamespace _xsl = "http://www.w3.org/1999/XSL/Transform";
This namespace is then used to create all XSLT elements, like:
new XElement(_xsl + "template", new XAttribute("match", match));
What the Code Can Do
This tool handles four main XML operations:
1. Change Version Attributes
Example JSON: "Version": "2.0"
What it does: Changes all version attributes in the XML to "2.0"
Generated XSLT:
<xsl:template match="//*[@Version]">
<xsl:copy>
<xsl:apply-templates select="@*[name()!='Version']"/>
<xsl:attribute name="Version">2.0</xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
2. Remove Elements or Attributes
Example JSON:
"Remove": {
"Attributes": ["oldAttribute", "unwantedField"],
"Elements": ["deprecatedElement"]
}
What it does: Removes specified attributes and elements from the XML
Generated XSLT:
<xsl:template match="@oldAttribute"/>
<xsl:template match="@unwantedField"/>
<xsl:template match="deprecatedElement"/>
3. Add Elements or Attributes
Example JSON:
"Add": {
"Attributes": {
"user": { "role": "admin", "level": "3" }
},
"Elements": {
"settings": {
"timeout": {
"_attributes": { "value": "30", "unit": "seconds" }
}
}
}
}
What it does: Adds attributes to specific elements and adds new elements to specific parents
Generated XSLT:
<xsl:template match="user">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="role">admin</xsl:attribute>
<xsl:attribute name="level">3</xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="settings">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
<xsl:element name="timeout">
<xsl:attribute name="value">30</xsl:attribute>
<xsl:attribute name="unit">seconds</xsl:attribute>
</xsl:element>
</xsl:copy>
</xsl:template>
4. Rename Elements or Attributes
Example JSON:
"Rename": {
"Attributes": {
"id": "identifier",
"type": "dataType"
},
"Elements": {
"item": "product",
"desc": "description"
}
}
What it does: Renames attributes and elements while preserving their values and structure
Generated XSLT:
<xsl:template match="//*[@id]">
<xsl:copy>
<xsl:attribute name="identifier">
<xsl:value-of select="@id"/>
</xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item">
<xsl:element name="product">
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
</xsl:element>
</xsl:template>
How the Code Works
-
Program.cs: The main program that:
- Finds all JSON files in the "Jsons" folder
- Creates XSLT transformations based on the JSON
- Saves the results to the "Xslt" folder
-
XsltBuilder: Creates the overall XSLT structure and processes operations
-
XsltTemplateBuilder: Builds individual XSLT templates with specific match patterns
-
ElementBuilder: Creates element structures with attributes and content
Quick JSON Example
{
"Operations": {
"Version": "2.0",
"Remove": {
"Attributes": ["oldAttr"],
"Elements": ["oldElem"]
},
"Add": {
"Attributes": {
"root": { "timestamp": "2025-03-31" }
}
},
"Rename": {
"Elements": {
"customer": "user"
}
}
}
}
This would transform:
<root>
<customer id="123" oldAttr="remove">
<oldElem>Will be removed</oldElem>
<info Version="1.0">Data</info>
</customer>
</root>
Into:
<root timestamp="2025-03-31">
<user id="123">
<info Version="2.0">Data</info>
</user>
</root>
Benefits of This Approach
- Simplicity: Write simple JSON instead of complex XSLT
- Consistency: All transformations follow the same patterns
- Maintainability: Easier to review and modify JSON than XSLT
- Automation: Batch process many transformations at once