XML Converter
JSON Format: Converts XML to JavaScript Object Notation (JSON) format. Perfect for web APIs and JavaScript applications.
Converted content copied to clipboard!
\n';
return html;
}
// XML to Excel conversion (CSV with BOM for Excel)
function xmlToExcel(xmlDoc) {
const csv = xmlToCsv(xmlDoc);
// Add UTF-8 BOM for Excel compatibility
return '\uFEFF' + csv;
}
// XML to Java conversion
function xmlToJava(xmlDoc) {
let javaCode = "import java.util.*;\n\n";
javaCode += "public class XmlData {\n";
// Function to generate Java class from XML
function generateClass(node, className) {
let classCode = ` public static class ${className} {\n`;
const fields = new Set();
const childClasses = [];
// Process attributes
if (node.attributes.length > 0) {
for (let attr of node.attributes) {
const fieldName = attr.nodeName.replace(/-/g, '_');
fields.add(` private String ${fieldName};\n`);
fields.add(` public String get${fieldName.charAt(0).toUpperCase() + fieldName.slice(1)}() { return ${fieldName}; }\n`);
fields.add(` public void set${fieldName.charAt(0).toUpperCase() + fieldName.slice(1)}(String ${fieldName}) { this.${fieldName} = ${fieldName}; }\n`);
}
}
// Process child elements
const childElements = Array.from(node.childNodes).filter(
child => child.nodeType === Node.ELEMENT_NODE
);
// Group children by name
const childrenByName = {};
childElements.forEach(child => {
if (!childrenByName[child.nodeName]) {
childrenByName[child.nodeName] = [];
}
childrenByName[child.nodeName].push(child);
});
Object.keys(childrenByName).forEach(childName => {
const children = childrenByName[childName];
const javaChildName = childName.charAt(0).toUpperCase() + childName.slice(1).replace(/-/g, '_');
if (children.length === 1 && !Array.from(children[0].childNodes).some(
c => c.nodeType === Node.ELEMENT_NODE
)) {
// Simple property
fields.add(` private String ${childName};\n`);
fields.add(` public String get${javaChildName}() { return ${childName}; }\n`);
fields.add(` public void set${javaChildName}(String ${childName}) { this.${childName} = ${childName}; }\n`);
} else {
// Complex type - generate nested class
const nestedClassName = className + javaChildName;
childClasses.push(generateClass(children[0], nestedClassName));
if (children.length > 1) {
fields.add(` private List<${nestedClassName}> ${childName} = new ArrayList<>();\n`);
fields.add(` public List<${nestedClassName}> get${javaChildName}() { return ${childName}; }\n`);
fields.add(` public void set${javaChildName}(List<${nestedClassName}> ${childName}) { this.${childName} = ${childName}; }\n`);
} else {
fields.add(` private ${nestedClassName} ${childName};\n`);
fields.add(` public ${nestedClassName} get${javaChildName}() { return ${childName}; }\n`);
fields.add(` public void set${javaChildName}(${nestedClassName} ${childName}) { this.${childName} = ${childName}; }\n`);
}
}
});
// Add text content field if exists
const textContent = node.textContent.trim();
if (textContent && childElements.length === 0) {
fields.add(" private String text;\n");
fields.add(" public String getText() { return text; }\n");
fields.add(" public void setText(String text) { this.text = text; }\n");
}
classCode += Array.from(fields).join('');
classCode += " }\n\n";
// Add nested classes
childClasses.forEach(childClass => {
classCode += childClass;
});
return classCode;
}
const rootName = xmlDoc.documentElement.nodeName;
const className = rootName.charAt(0).toUpperCase() + rootName.slice(1).replace(/-/g, '_');
javaCode += generateClass(xmlDoc.documentElement, className);
javaCode += ` private ${className} ${rootName};\n`;
javaCode += ` public ${className} get${className}() { return ${rootName}; }\n`;
javaCode += ` public void set${className}(${className} ${rootName}) { this.${rootName} = ${rootName}; }\n`;
javaCode += "}\n";
return javaCode;
}
// Beautify XML
function beautifyXml(xmlString) {
try {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
// Check for parsing errors
const errorNode = xmlDoc.querySelector("parsererror");
if (errorNode) {
throw new Error("Invalid XML: " + errorNode.textContent);
}
const serializer = new XMLSerializer();
const beautified = serializer.serializeToString(xmlDoc);
// Add indentation
let formatted = '';
let indent = '';
const tab = ' ';
beautified.split(/>\s*).forEach((element, index) => {
if (index === 0) {
formatted += element + '>\n<';
} else {
if (element.match(/^\/\w/)) {
indent = indent.substring(tab.length);
}
formatted += indent + '<' + element + '>\n';
if (!element.match(/^\/\w/) && !element.match(/\/$/) && !element.match(/^!/)) {
indent += tab;
}
}
});
return formatted.substring(0, formatted.length - 1);
} catch (error) {
throw new Error("Failed to beautify XML: " + error.message);
}
}
// Download file function
function downloadFile(content, filename, mimeType) {
// Create a blob with the content
const blob = new Blob([content], { type: mimeType });
// Create a temporary link element
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
// Append to the document, click it, and remove it
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// Clean up the URL object
setTimeout(() => {
URL.revokeObjectURL(link.href);
}, 100);
}
// Generate filename based on format and timestamp
function generateFilename() {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T')[0];
const extension = formatExtensions[currentFormat] || '.txt';
return `xml-converted-${timestamp}-${Date.now()}${extension}`;
}
// Download converted result
function downloadConvertedResult() {
const content = outputContent.value.trim();
if (!content) {
showToast("No content to download");
return;
}
const filename = generateFilename();
const mimeType = formatMimeTypes[currentFormat] || 'text/plain';
downloadFile(content, filename, mimeType);
showToast("File downloaded successfully!");
}
// Download input XML
function downloadInputXml() {
const content = inputXml.value.trim();
if (!content) {
showToast("No XML input to download");
return;
}
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T')[0];
const filename = `xml-input-${timestamp}-${Date.now()}.xml`;
downloadFile(content, filename, 'application/xml');
showToast("XML file downloaded!");
}
// Main conversion function
function convertXml() {
const startTime = performance.now();
const xmlString = inputXml.value.trim();
if (!xmlString) {
showError("Please enter XML to convert");
return;
}
try {
const xmlDoc = parseXML(xmlString);
let result;
switch (currentFormat) {
case 'json':
result = xmlToJson(xmlDoc);
break;
case 'yaml':
result = xmlToYaml(xmlDoc);
break;
case 'csv':
result = xmlToCsv(xmlDoc);
break;
case 'tsv':
result = xmlToTsv(xmlDoc);
break;
case 'text':
result = xmlToText(xmlDoc);
break;
case 'xsl':
const xsltString = xsltContent.value.trim();
if (!xsltString) {
showError("Please enter XSLT for transformation");
return;
}
result = xsltTransform(xmlDoc, xsltString);
break;
case 'html':
result = xmlToHtml(xmlDoc);
break;
case 'excel':
result = xmlToExcel(xmlDoc);
break;
case 'java':
result = xmlToJava(xmlDoc);
break;
default:
result = xmlToJson(xmlDoc);
}
outputContent.value = result;
// Update conversion time
const endTime = performance.now();
conversionTime.textContent = Math.round(endTime - startTime) + 'ms';
} catch (error) {
showError(error.message);
}
updateCounts();
}
// Show error message
function showError(message) {
outputContent.value = `Error: ${message}`;
outputContent.style.color = '#dc2626';
setTimeout(() => {
outputContent.style.color = '';
}, 3000);
updateCounts();
}
// Show toast notification
function showToast(message) {
toast.innerHTML = `
${message}`;
toast.style.display = 'flex';
setTimeout(() => {
toast.style.display = 'none';
}, 3000);
}
// Copy to clipboard
function copyToClipboard() {
if (!outputContent.value.trim()) {
showToast("No content to copy");
return;
}
outputContent.select();
outputContent.setSelectionRange(0, 99999);
try {
navigator.clipboard.writeText(outputContent.value);
showToast("Converted content copied to clipboard!");
} catch (err) {
// Fallback for older browsers
document.execCommand('copy');
showToast("Content copied to clipboard!");
}
}
// Copy output to clipboard (from output button)
function copyOutputToClipboard() {
if (!outputContent.value.trim()) {
showToast("No output to copy");
return;
}
outputContent.select();
outputContent.setSelectionRange(0, 99999);
try {
navigator.clipboard.writeText(outputContent.value);
showToast("Output copied to clipboard!");
} catch (err) {
document.execCommand('copy');
showToast("Output copied to clipboard!");
}
}
// Validate XML
function validateXml() {
const xmlString = inputXml.value.trim();
if (!xmlString) {
showError("Please enter XML to validate");
return;
}
try {
const xmlDoc = parseXML(xmlString);
showToast("XML is valid!");
} catch (error) {
showError(error.message);
}
}
// Beautify XML input
function beautifyXmlInput() {
const xmlString = inputXml.value.trim();
if (!xmlString) {
showError("Please enter XML to beautify");
return;
}
try {
const beautified = beautifyXml(xmlString);
inputXml.value = beautified;
showToast("XML beautified successfully!");
updateCounts();
} catch (error) {
showError(error.message);
}
}
// Clear all fields
function clearAll() {
inputXml.value = '';
outputContent.value = '';
xsltContent.value = '';
conversionTime.textContent = '0ms';
updateCounts();
showToast("All fields cleared");
}
// Event Listeners
inputXml.addEventListener('input', updateCounts);
outputContent.addEventListener('input', updateCounts);
convertBtn.addEventListener('click', convertXml);
copyBtn.addEventListener('click', copyToClipboard);
downloadBtn.addEventListener('click', downloadConvertedResult);
clearBtn.addEventListener('click', clearAll);
validateBtn.addEventListener('click', validateXml);
beautifyBtn.addEventListener('click', beautifyXmlInput);
// Output action buttons
outputCopyBtn.addEventListener('click', copyOutputToClipboard);
outputDownloadBtn.addEventListener('click', downloadConvertedResult);
// Auto-convert on format change if there's content
formatBtns.forEach(btn => {
btn.addEventListener('click', function() {
if (inputXml.value.trim()) {
setTimeout(convertXml, 100);
}
});
});
// Add context menu for download option on input XML
inputXml.addEventListener('contextmenu', function(e) {
e.preventDefault();
// Create a simple context menu for download
if (inputXml.value.trim()) {
downloadInputXml();
}
});
// Initial conversion
convertXml();
});