我正在尝试做的事情:有一个自动化系统可以生成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>
遗憾的是它什么也没做,将生成一个空白文件。我希望有人可以指出我在这里做错了什么。
您缺少所有元素都在元素上定义的默认名称空间中的事实
<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>