如何通过XSLT转换将XML导入Access并按需生成多表?
解决方案:批量转换XML并导入Access 2016
核心思路
通过修改XSLT实现批量遍历所有parameter节点,自动生成符合Access导入要求的XML结构,每个parameter对应一个独立表,无需手动重复操作。同时可配合Access VBA实现转换+导入全自动化。
1. 批量处理XSLT代码
以下XSLT会遍历原始XML中所有parameter节点,将每个节点转换为Access可识别的表结构,表名取自parameter下的name标签,每行数据对应一个产品的article和property:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <!-- 生成Access识别的根节点 --> <xsl:template match="/"> <dataroot xmlns:od="urn:schemas-microsoft-com:officedata"> <!-- 遍历所有parameter节点 --> <xsl:for-each select="//parameter"> <!-- 获取当前parameter的名称作为表名,自动清理适配Access规则 --> <xsl:variable name="tableName"> <xsl:call-template name="cleanTableName"> <xsl:with-param name="input" select="name"/> </xsl:call-template> </xsl:variable> <!-- 遍历当前parameter下的所有产品 --> <xsl:for-each select=".//product"> <!-- 生成对应表的行节点 --> <xsl:element name="{$tableName}"> <article><xsl:value-of select="article"/></article> <property><xsl:value-of select="property"/></property> </xsl:element> </xsl:for-each> </xsl:for-each> </dataroot> </xsl:template> <!-- 清理表名,适配Access命名规则 --> <xsl:template name="cleanTableName"> <xsl:param name="input"/> <xsl:choose> <!-- 替换空格为下划线 --> <xsl:when test="contains($input, ' ')"> <xsl:call-template name="cleanTableName"> <xsl:with-param name="input" select="concat(substring-before($input, ' '), '_', substring-after($input, ' '))"/> </xsl:call-template> </xsl:when> <!-- 移除特殊字符 --> <xsl:when test="contains($input, '&') or contains($input, '*') or contains($input, '/')"> <xsl:call-template name="cleanTableName"> <xsl:with-param name="input" select="translate($input, '&*/', '')"/> </xsl:call-template> </xsl:when> <!-- 数字开头的表名添加前缀T_ --> <xsl:when test="starts-with($input, '0') or starts-with($input, '1') or starts-with($input, '2') or starts-with($input, '3') or starts-with($input, '4') or starts-with($input, '5') or starts-with($input, '6') or starts-with($input, '7') or starts-with($input, '8') or starts-with($input, '9')"> <xsl:value-of select="concat('T_', $input)"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$input"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
XSLT关键说明
<dataroot>是Access导入XML时的标准根节点,必须保留cleanTableName模板自动处理不符合Access规则的表名(如空格、特殊字符、数字开头),避免导入失败- 动态生成表名和行数据,一次性处理所有
parameter节点
2. 使用方法
方式一:手动转换+导入
- 将上述XSLT保存为
BatchTransform.xslt - 使用XML转换工具(如VS Code的XML插件、本地XML编辑器)加载原始XML和XSLT,生成转换后的XML文件
- 打开Access 2016,点击外部数据 → XML文件,选择转换后的XML,勾选结构和数据,完成导入
方式二:Access VBA自动化(推荐)
直接在Access中编写VBA,自动完成转换+导入,适合大型文件和批量场景:
Sub BatchImportXML() Dim xmlDoc As Object, xsltDoc As Object, resultDoc As Object Dim inputPath As String, xsltPath As String, outputPath As String ' 替换为你的实际文件路径 inputPath = "C:\YourOriginalXML.xml" xsltPath = "C:\BatchTransform.xslt" outputPath = "C:\Transformed_Output.xml" ' 创建XML处理对象 Set xmlDoc = CreateObject("MSXML2.DOMDocument.6.0") Set xsltDoc = CreateObject("MSXML2.DOMDocument.6.0") Set resultDoc = CreateObject("MSXML2.DOMDocument.6.0") ' 加载文件(禁用异步加载避免错误) xmlDoc.async = False xmlDoc.Load inputPath xsltDoc.async = False xsltDoc.Load xsltPath ' 执行转换并保存结果 xmlDoc.transformNodeToObject xsltDoc, resultDoc resultDoc.Save outputPath ' 导入转换后的XML到Access Application.ImportXML outputPath, acStructureAndData ' 清理对象 Set xmlDoc = Nothing Set xsltDoc = Nothing Set resultDoc = Nothing MsgBox "批量导入完成!" End Sub
VBA使用步骤
- 打开Access,按
Alt+F11打开VBA编辑器 - 插入模块,粘贴上述代码
- 修改文件路径为实际路径
- 运行宏,等待自动完成转换和导入
注意事项
- 确保原始XML中每个
parameter下的产品节点路径统一(如示例中的product节点),若路径不同需调整XSLT中的select=".//product"为实际路径 - Access表名长度不能超过64字符,若
name标签过长需在cleanTableName模板中添加截断逻辑 - 若
article是纯数字且需保留前导零(如012968),导入时需确保Access将其识别为文本类型,可在转换后的XML中为article节点添加类型属性,或在导入后手动修改字段类型
内容的提问来源于stack exchange,提问作者loarrin
相关产品推荐
相关产品推荐

