通用XSLT实现无嵌套XML转JSON的可行性及方法
Generic Flat XML to JSON XSLT Solution
Absolutely! For flat XML structures (no nested elements under the root, just direct key-value pairs), you can create a fully generic XSLT that doesn't require hardcoding any element names—just like the XML-to-CSV approach you referenced. Here's a practical implementation:
Core Approach
The logic is simple and flexible:
- Target the root element of your XML
- Iterate over all its direct child elements
- Map each element’s name to a JSON key, and its text content to the corresponding value
- Ensure the output follows valid JSON syntax (proper quoting, no trailing commas, etc.)
Generic XSLT Code
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8" indent="yes"/> <!-- Match the root node to start building the JSON object --> <xsl:template match="/"> <xsl:text>{</xsl:text> <!-- Process every direct child element of the root --> <xsl:for-each select="*/*"> <!-- Write the JSON key (element name) --> <xsl:text>"</xsl:text> <xsl:value-of select="local-name()"/> <xsl:text>": "</xsl:text> <!-- Write the JSON value, escaping double quotes to avoid invalid JSON --> <xsl:value-of select="replace(., '"', '\"')"/> <xsl:text>"</xsl:text> <!-- Add a comma only if this isn't the last element --> <xsl:if test="position() != last()"> <xsl:text>,</xsl:text> </xsl:if> </xsl:for-each> <xsl:text>}</xsl:text> </xsl:template> <!-- Ignore empty whitespace text nodes to keep output clean --> <xsl:template match="text()[not(normalize-space())]"/> </xsl:stylesheet>
How It Works
Let’s break down the key components:
- Root Matching: The top template starts the JSON object with
{and targets the root of your XML (works with any root name, like your<POSTrans>example). - Element Traversal:
*/*selects all direct children of the root, so you don’t need to specify element names upfront. - Value Escaping: The
replace()function handles double quotes in element text, preventing them from breaking the JSON structure. - Comma Management: The
position() != last()check ensures we don’t add a trailing comma, which would make the JSON invalid. - Whitespace Cleanup: The final template filters out empty whitespace nodes that might otherwise clutter the output.
Test with Your Sample XML
Using your example snippet (extended with a few more elements for clarity):
<POSTrans> <POSDocNo>INV1200004K89</POSDocNo> <Invoice_Exchange>Invoice</Invoice_Exchange> <CustomerID>CUST-789</CustomerID> <Total>299.99</Total> </POSTrans>
Applying the XSLT will output valid JSON:
{ "POSDocNo": "INV1200004K89", "Invoice_Exchange": "Invoice", "CustomerID": "CUST-789", "Total": "299.99" }
Edge Case Adjustments
- Empty Elements: If an element has no text, it will output as
"ElementName": ""(valid JSON). - Additional Escaping: To handle backslashes or other special characters, add extra
replace()calls (e.g.,replace(replace(., '"', '\"'), '\\', '\\\\')). - XSLT 1.0 Compatibility: If you’re limited to XSLT 1.0, replace the
replace()function with a recursive escaping template— the core traversal logic stays the same.
内容的提问来源于stack exchange,提问作者paul
相关产品推荐
相关产品推荐

