You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java实现无XSLT的XML属性转标签及通用XML合并方案

Alright, let's break this down. You need two key tasks done in pure Java (no XSLT): converting XML attributes to elements, and merging two XML files where one has a full element structure and the other stores corresponding data as attributes. Plus, you want this to work generically for multiple XML pairs. Here's a complete, reusable solution using Java's built-in DOM API—no external libraries needed:

First, let's define the sample inputs you referenced to ground the solution:

Sample Inputs

Element-Structured XML (Input 1)

<PROPERTIES>
  <PROPERTY>
    <ADDRESS>
      <AddressLineText></AddressLineText>
      <CityName>New York</CityName>
      <PostalCode>10001</PostalCode>
    </ADDRESS>
  </PROPERTY>
</PROPERTIES>

Attribute-Based XML (Input 2)

<PROPERTIES>
  <PROPERTY AddressLineText="123 Main St" CityName="New York" PostalCode="10001"/>
</PROPERTIES>

1. Attribute-to-Element Conversion

This recursive method will scan every node in your XML and turn all attributes into child elements. It works for nested structures too.

Reusable Utility Class

import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.StringWriter;

public class XmlProcessor {

    // Convert all attributes in a node (and its children) to child elements
    public static void attributesToElements(Node node) {
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            Element element = (Element) node;
            // Process attributes in reverse order to avoid index shifting issues
            NamedNodeMap attributes = element.getAttributes();
            for (int i = attributes.getLength() - 1; i >= 0; i--) {
                Attr attr = (Attr) attributes.item(i);
                // Create a new element with the attribute's name
                Element attrElement = element.getOwnerDocument().createElement(attr.getName());
                attrElement.setTextContent(attr.getValue());
                // Add the new element as a child, then remove the original attribute
                element.appendChild(attrElement);
                element.removeAttributeNode(attr);
            }
            // Recurse through all child nodes
            NodeList children = element.getChildNodes();
            for (int i = 0; i < children.getLength(); i++) {
                attributesToElements(children.item(i));
            }
        }
    }

    // Helper: Load XML from a file
    public static Document loadXml(File file) throws Exception {
        return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
    }

    // Helper: Save XML document to a file
    public static void saveXml(Document doc, File output) throws Exception {
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
        transformer.transform(new DOMSource(doc), new StreamResult(output));
    }

    // Helper: Convert document to a formatted string for debugging
    public static String docToString(Document doc) throws Exception {
        StringWriter writer = new StringWriter();
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
        transformer.transform(new DOMSource(doc), new StreamResult(writer));
        return writer.toString();
    }
}

How to Use It

public class AttributeConversionDemo {
    public static void main(String[] args) throws Exception {
        File input = new File("path/to/attribute-based.xml");
        File output = new File("path/to/converted-element.xml");

        Document doc = XmlProcessor.loadXml(input);
        XmlProcessor.attributesToElements(doc.getDocumentElement());
        XmlProcessor.saveXml(doc, output);

        System.out.println("Converted XML:\n" + XmlProcessor.docToString(doc));
    }
}

2. Merging Element-Structured and Attribute-Based XMLs

This method will match nodes by tag name (you can extend this to use unique IDs if needed) and fill the empty elements in your structure XML with values from the attribute-based XML.

Add This Method to XmlProcessor

// Merge attribute-based data into the element-structured XML
public static void mergeXml(Document structureDoc, Document attributeDoc) {
    Element structureRoot = structureDoc.getDocumentElement();
    Element attributeRoot = attributeDoc.getDocumentElement();
    // Start merging from the root nodes
    mergeMatchingNodes(structureRoot, attributeRoot);
}

private static void mergeMatchingNodes(Element structureNode, Element attributeNode) {
    // Skip if node tags don't match
    if (!structureNode.getTagName().equals(attributeNode.getTagName())) {
        return;
    }

    // Fill structure elements with attribute values
    NamedNodeMap attributes = attributeNode.getAttributes();
    for (int i = 0; i < attributes.getLength(); i++) {
        Attr attr = (Attr) attributes.item(i);
        // Find the corresponding element in the structure XML
        Element targetElement = (Element) structureNode.getElementsByTagName(attr.getName()).item(0);
        if (targetElement != null) {
            targetElement.setTextContent(attr.getValue());
        }
    }

    // Recurse through child nodes to merge nested data
    NodeList structureChildren = structureNode.getChildNodes();
    NodeList attributeChildren = attributeNode.getChildNodes();
    for (int i = 0; i < structureChildren.getLength(); i++) {
        Node structChild = structureChildren.item(i);
        if (structChild.getNodeType() == Node.ELEMENT_NODE) {
            // Find the matching child in the attribute XML
            for (int j = 0; j < attributeChildren.getLength(); j++) {
                Node attrChild = attributeChildren.item(j);
                if (attrChild.getNodeType() == Node.ELEMENT_NODE && 
                    attrChild.getTagName().equals(structChild.getTagName())) {
                    mergeMatchingNodes((Element) structChild, (Element) attrChild);
                    break;
                }
            }
        }
    }
}

How to Use the Merge

public class XmlMergeDemo {
    public static void main(String[] args) throws Exception {
        File structureFile = new File("path/to/element-structure.xml");
        File attributeFile = new File("path/to/attribute-data.xml");
        File mergedOutput = new File("path/to/merged-result.xml");

        Document structureDoc = XmlProcessor.loadXml(structureFile);
        Document attributeDoc = XmlProcessor.loadXml(attributeFile);

        XmlProcessor.mergeXml(structureDoc, attributeDoc);
        XmlProcessor.saveXml(structureDoc, mergedOutput);

        System.out.println("Merged XML:\n" + XmlProcessor.docToString(structureDoc));
    }
}

Sample Merged Output

<PROPERTIES>
  <PROPERTY>
    <ADDRESS>
      <AddressLineText>123 Main St</AddressLineText>
      <CityName>New York</CityName>
      <PostalCode>10001</PostalCode>
    </ADDRESS>
  </PROPERTY>
</PROPERTIES>

Customization Tips

  • Matching Logic: If your XML uses unique identifiers (like id attributes), modify mergeMatchingNodes to match using those instead of tag names for better accuracy.
  • Large Files: For very large XMLs, swap DOM for SAX to avoid loading the entire document into memory.
  • Error Handling: Add checks for missing elements/attributes or validation logic to fit your specific use case.

内容的提问来源于stack exchange,提问作者adbdkb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:17:24