温馨提示:本文翻译自stackoverflow.com,查看原文请点击:vba - Import XML files in MS Access using an XSL transformation
ms-access vba xml xslt

vba - 使用XSL转换在MS Access中导入XML文件

发布于 2020-04-11 00:05:24

我正在尝试做的事情:有一个自动化系统可以生成10k XML文件。我想将所有这些文件读入MS Access数据库。为了导入文件(使用VBA ImportXML功能),我需要FormatXML使用XSL样式表使用VBA 功能转换文件

我在Google上搜索了一些内容,但似乎无法正常使用。这是XML文件的外观(基于机密性原因,我无法显示真实文件,但结构如下所示):

<?xml version="1.0" encoding="UTF-16"?>
<Album xmlns="x-schema:ConfigFileSchema.xml">
    <Informations>
        <General>
            <Name>Name of Album</Name>
            <Band>Name of Band</Band>
        </General>
        <Parameters>
            <Parameter>
                <ParamName>Length of Album</ParamName>
                <ParamValue>57:16</ParamValue>
            </Parameter>
            <Parameter>
                <ParamName>Year</ParamName>
                <ParamValue>2020</ParamValue>
            </Parameter>
        </Parameters>
        <Tracks>
            <Track>
                <Trackdef>
                    <TrackName>Name of Track</TrackName>
                    <TrackLength>3:30</TrackLength>
                </Trackdef>
                <Parameters>
                    <Parameter>
                        <ParamName>Features</ParamName>
                        <ParamValue>...</ParamValue>
                    </Parameter>
                    <Parameter>
                        <ParamName>Some other Parameters</ParamName>
                        <ParamValue>...</ParamValue>
                    </Parameter>
                    <Parameter>
                        <ParamName>Some other Parameters</ParamName>
                        <ParamValue>...</ParamValue>
                    </Parameter>
                </Parameters>
            </Track>
            <Track>
                <Trackdef>
                    <TrackName>Name of Track</TrackName>
                    <TrackLength>3:30</TrackLength>
                </Trackdef>
                <Parameters>
                    <Parameter>
                        <ParamName>Features</ParamName>
                        <ParamValue>...</ParamValue>
                    </Parameter>
                    <Parameter>
                        <ParamName>Some other Parameters</ParamName>
                        <ParamValue>...</ParamValue>
                    </Parameter>
                    <Parameter>
                        <ParamName>Some other Parameters</ParamName>
                        <ParamValue>...</ParamValue>
                    </Parameter>
                </Parameters>
            </Track>
        </Tracks>
    </Informations>
</Album>

我想做一些非常简单的转换,以使TransformXML的输出XML看起来像这样:

<?xml version="1.0"?>
<Information>
    <Track>
        <Parameter>
            <ParamName>Features</ParamName>
            <ParamValue>...</ParamValue>
        </Parameter>
        <Parameter>
            <ParamName>Some other Parameters</ParamName>
            <ParamValue>...</ParamValue>
        </Parameter>
    </Track>
    <Track>
        <Parameter>
            <ParamName>Features</ParamName>
            <ParamValue>...</ParamValue>
        </Parameter>
        <Parameter>
            <ParamName>Some other Parameters</ParamName>
            <ParamValue>...</ParamValue>
        </Parameter>
    </Track>
</Information>

使用此XSLT:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/Album/Informations/Tracks/Track/Parameters">
        <Information>
            <xsl:for-each select="child::Parameter">
                <Parameter>
                    <xsl:copy-of select="child::ParamName"/>
                    <xsl:copy-of select="child::ParamValue"/>
                </Parameter>
            </xsl:for-each>
        </Information>
        <xsl:apply-templates/>
    </xsl:template>
</xsl:stylesheet>

遗憾的是它什么也没做,将生成一个空白文件。我希望有人可以指出我在这里做错了什么。

查看更多

提问者
Dimbst
被浏览
63
zx485 2020-02-02 05:19

您缺少所有元素都在元素上定义的默认名称空间中的事实

<Album xmlns="x-schema:ConfigFileSchema.xml">

您还必须在XSLT中定义该名称空间,以正确访问其元素。这可以通过属性来实现

xmlns:x="x-schema:ConfigFileSchema.xml"

在你的xsl:stylesheet元素上。要在输出中摆脱此命名空间,还请添加属性

exclude-result-prefixes="x"

xsl:stylesheet元素。
因此整个样式表可能如下所示。要获得唯一参数,取决于TrackName唯一性,因为它用于创建键值。当然,您可以将其更改为另一个唯一值(但请在两个地方都进行定义和使用)。

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:x="x-schema:ConfigFileSchema.xml" exclude-result-prefixes="x">
    <xsl:output method="xml" indent="yes" />
    <xsl:key name="params" match="x:Parameters/x:Parameter" use="concat(x:ParamName,../../x:Trackdef/x:TrackName)" />

    <xsl:template match="text()" />

    <xsl:template match="/">
        <Information>
            <xsl:apply-templates select="node()|@*" />
        </Information>
    </xsl:template>

    <xsl:template match="/x:Album/x:Informations/x:Tracks/x:Track">
        <Track>
            <xsl:for-each select="x:Parameters/x:Parameter[generate-id() = generate-id(key('params',concat(x:ParamName,../../x:Trackdef/x:TrackName))[1])]">
                <Parameter>
                    <ParamName><xsl:value-of  select="x:ParamName"/></ParamName>
                    <ParamValue><xsl:value-of select="x:ParamValue"/></ParamValue>
                </Parameter>
            </xsl:for-each>
        </Track>
    </xsl:template>

</xsl:stylesheet>

其输出为:

<?xml version="1.0"?>
<Information>
  <Track>
    <Parameter>
      <ParamName>Features</ParamName>
      <ParamValue>...</ParamValue>
    </Parameter>
    <Parameter>
      <ParamName>Some other Parameters</ParamName>
      <ParamValue>...</ParamValue>
    </Parameter>
  </Track>
  <Track>
    <Parameter>
      <ParamName>Features</ParamName>
      <ParamValue>...</ParamValue>
    </Parameter>
    <Parameter>
      <ParamName>Some other Parameters</ParamName>
      <ParamValue>...</ParamValue>
    </Parameter>
  </Track>
</Information>