考虑一个参数化的 XSLT,您可以在其中迭代 Excel 文件的行并将它们作为参数从 VBA 传递到 XSLT。 Windows 的 MSXML 库通过 processor object 支持此方法。
输入 XML (例如“模板”)
<?xml version="1.0" encoding="UTF-8"?>
<root>
<nummer></nummer>
<kunde></kunde>
<titel></titel>
<datum></datum>
<system></system>
<dauer></dauer>
</root>
XSLT (另存为.xsl文件,特殊的.xml文件)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:param name="nummer" />
<xsl:param name="kunde" />
<xsl:param name="titel" />
<xsl:param name="datum" />
<xsl:param name="system" />
<xsl:param name="dauer" />
<!-- IDENTITY TRANFORM -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/root">
<xsl:copy>
<nummer><xsl:value-of select="$nummer"/></nummer>
<kunde><xsl:value-of select="$kunde"/></kunde>
<titel><xsl:value-of select="$titel"/></titel>
<datum><xsl:value-of select="$datum"/></datum>
<system><xsl:value-of select="$system"/></system>
<dauer><xsl:value-of select="$dauer"/></dauer>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
VBA (参数名称必须与上面的 XSLT 匹配)
Sub Param_XSLT_Process()
On Error GoTo ErrHandle
' ADD REFERENCE Microsoft XML, v6.0
Dim xmldoc As New MSXML2.DOMDocument60, newDoc As New MSXML2.DOMDocument60
Dim xslDoc As New MSXML2.FreeThreadedDOMDocument60
Dim xslTemp As New MSXML2.XSLTemplate60
Dim xslProc As Object
Dim lLastRow As Long, lRow As Long
' LOAD XML AND XSL FILES
xmldoc.async = False
xmldoc.Load "C:\Path\To\Input.xml"
xslDoc.async = False
xslDoc.setProperty "AllowDocumentFunction", True
xslDoc.Load "C:\Path\To\XSLT\Script.xsl"
' INITIALIZE NEEDED OBJECTS
Set xslTemp.stylesheet = xslDoc
Set xslProc = xslTemp.createProcessor()
xslProc.input = xmldoc
' ITERATE THROUGH EACH ROW, TRANSFORM, SAVE XML OUTPUT
With ActiveWorkbook.Worksheets(1)
lLastRow = .UsedRange.Rows.Count
For lRow = 2 To lLastRow
xslProc.addParameter "kunde", CStr(.Cells(lRow, 1).Value) ' ADD PARAMETER(S)
xslProc.addParameter "nummer", CStr(.Cells(lRow, 2).Value)
xslProc.addParameter "dauer", CStr(.Cells(lRow, 3).Value)
xslProc.addParameter "titel", CStr(.Cells(lRow, 4).Value)
xslProc.addParameter "system", CStr(.Cells(lRow, 5).Value)
xslProc.addParameter "datum", CStr(.Cells(lRow, 6).Value)
xslProc.transform ' TRANSFORM XML
newDoc.LoadXML xslProc.output ' LOAD RESULT TREE
newDoc.Save "C:\Path\To\Output_" & lRow - 1 & ".xml" ' SAVE OUTPUT TO FILE
Next lRow
End With
MsgBox "Successfully processed XML files!", vbInformation
ExitHandle:
Set xmldoc = Nothing: Set newDoc = Nothing
Set xslDoc = Nothing: Set xslTemp = Nothing: Set xslProc = Nothing
Exit Sub
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical
Err.Raise xslDoc.parseError.ErrorCode, , xslDoc.parseError.reason
Resume ExitHandle
End Sub
实际 XML
请考虑使用此 XSLT,它会调整 <category name="Archivalie_Categories_Attributes:Archivalie"> 下的前 6 个属性/项目节点并保持其他所有内容相同。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:param name="nummer" />
<xsl:param name="kunde" />
<xsl:param name="titel" />
<xsl:param name="datum" />
<xsl:param name="system" />
<xsl:param name="dauer" />
<!-- IDENTITY TRANFORM -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="category[@name='Archivalie_Categories_Attributes:Archivalie']">
<xsl:copy>
<xsl:copy-of select="@*"/>
<attribute dateformat="" name="Mandant">
<item><xsl:value-of select="$nummer"/></item>
</attribute>
<attribute dateformat="" name="Bemerkungen zur Stufe">
<item><xsl:value-of select="$kunde"/></item>
</attribute>
<attribute dateformat="" name="Signatur">
<item><xsl:value-of select="$titel"/></item>
</attribute>
<attribute dateformat="" name="Titel">
<item><xsl:value-of select="$datum"/></item>
</attribute>
<attribute dateformat="" name="Bemerkungen">
<item><xsl:value-of select="$system"/></item>
</attribute>
<attribute dateformat="" name="Versicherungswert">
<item><xsl:value-of select="$dauer"/></item>
</attribute>
<xsl:apply-templates select="attribute[position() > 6]|set"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>