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

使用Java与XSL将XML和XSD转换为指定格式CSV文件

解决方案:结合XSD约束生成指定格式CSV

问题背景

已通过Java+XSL实现XML到CSV的转换,现需结合XSD中元素的*minOccurs*、*maxOccurs*约束,生成包含约束信息的特定结构CSV。尝试在XSL中导入XSD未成功,需可行方案。

现有代码及示例:

Java转换代码

public static void xmlToCSV() throws Exception{
        File stylesheet = new File("style.xsl");
        File xmlSource = new File("xmlData.xml");

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(xmlSource);

        StreamSource stylesource = new StreamSource(stylesheet);
        Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
        Source source = new DOMSource(document);
        Result outputTarget = new StreamResult(new File("output.csv"));
        transformer.transform(source, outputTarget);
    }

原XSL文件(style.xsl)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xsl:template match="Person">
    <xsl:value-of select="Name"/>
    <xsl:text>,</xsl:text>
    <xsl:value-of select="Gender"/>
    <xsl:text>,</xsl:text>
    <xsl:value-of select="Age"/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

源XML(xmlData.xml)

<?xml version="1.0" encoding="UTF-8"?>
<Document>
    <Person>
        <Name>Bob</Name>
        <Gender>m</Gender>
        <Age>19</Age>
    </Person>
</Document>

XSD约束片段

<xs:element maxOccurs="1" minOccurs="1" name="Name">
<xs:element maxOccurs="1" minOccurs="1" name="Gender">
<xs:element maxOccurs="1" minOccurs="0" name="Age">

期望输出CSV

name,min,max,value
Bob,1,1,Name
m,1,1,Gender
19,0,1,Age

实现方案

XSLT 1.0无法直接导入XSD并解析约束,但可以通过*document()*函数加载XSD文件,在处理XML元素时查询对应的约束属性。以下是具体步骤:

1. 修改XSL文件(style.xsl)

更新后的XSL会先输出CSV表头,然后遍历Person下的所有子元素,从XSD中匹配对应元素的*minOccurs*和*maxOccurs*值,按格式输出每行内容:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <!-- 定义XSD文件路径,确保和XML文件同目录,或使用绝对路径 -->
    <xsl:variable name="xsdDoc" select="document('schema.xsd')"/>

    <!-- 匹配根节点,输出CSV表头 -->
    <xsl:template match="/">
        <xsl:text>name,min,max,value&#10;</xsl:text>
        <xsl:apply-templates select="Document/Person/*"/>
    </xsl:template>

    <!-- 处理Person下的每个子元素 -->
    <xsl:template match="Person/*">
        <!-- 获取当前元素的名称 -->
        <xsl:variable name="elemName" select="local-name()"/>
        
        <!-- 从XSD中查找对应元素的minOccurs和maxOccurs -->
        <xsl:variable name="xsdElem" select="$xsdDoc//xs:element[@name=$elemName]"/>
        
        <!-- 输出当前元素值、minOccurs、maxOccurs、元素名称 -->
        <xsl:value-of select="."/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$xsdElem/@minOccurs"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$xsdElem/@maxOccurs"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$elemName"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>

</xsl:stylesheet>

2. 调整Java代码(可选)

如果XSD文件路径不是相对路径,或者遇到文件加载问题,可以给Transformer设置URIResolver来指定XSD的加载路径:

public static void xmlToCSV() throws Exception{
        File stylesheet = new File("style.xsl");
        File xmlSource = new File("xmlData.xml");
        File xsdSource = new File("schema.xsd"); // 你的XSD文件

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(xmlSource);

        StreamSource stylesource = new StreamSource(stylesheet);
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        
        // 设置URIResolver,确保XSL能正确加载XSD
        transformerFactory.setURIResolver(new URIResolver() {
            @Override
            public Source resolve(String href, String base) throws TransformerException {
                if ("schema.xsd".equals(href)) {
                    return new StreamSource(xsdSource);
                }
                return null;
            }
        });

        Transformer transformer = transformerFactory.newTransformer(stylesource);
        Source source = new DOMSource(document);
        Result outputTarget = new StreamResult(new File("output.csv"));
        transformer.transform(source, outputTarget);
    }

3. 注意事项

  • 确保XSD文件的路径在XSL的*document()*函数中能正确访问,建议将XSD、XML、XSL放在同一目录下。
  • 如果XSD中有命名空间,需要在XSL中正确声明并调整XPath查询(比如$xsdDoc//xs:element[@name=$elemName]可能需要加上命名空间前缀的匹配)。
  • 若XSD中元素嵌套在复杂类型内,需要调整XPath表达式来定位到对应的xs:element节点。

内容的提问来源于stack exchange,提问作者Akito The Duck

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:43:21