gpt4 book ai didi

excel - 如何更改此基于 VBA/XSLT 的代码,以便将输出写入单个 XML 文件

转载 作者:行者123 更新时间:2023-12-04 21:49:00 25 4
gpt4 key购买 nike

由于上一个问题,我得到了以下代码。

代码的含义是遍历一个 excelsheet 并自动用单元格内容填充 XML 标记。输出是此 excelsheet 中每一行的 XML 文件。

现在我有一个非常相似的案例,我知道,要完成它不会有太多改变。我希望我的代码不是为每一行创建一个新的 XML 文件,而是在同一个 XML 文件中填充所有内容。

我想自动填写这个excel表的内容:

excelfile

进入一个最初看起来像这样的 XML 模板:

<?xml version="1.0" encoding="UTF-8"?>
<Codes>
<AreaCodes>
<Area>
<Name></Name>
<Desc/>
<Facility_Area></Facility_Area>
</Area>
</AreaCodes>
</Codes>

FACILITY 列必须在 Facility_Area-Tag 中移动。

必须在名称标签中移动 AREA 列。

Area 内的所有嵌套标签都应该重复。

对于我的 Excel 示例,输出应如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<Codes>
<AreaCodes>
<Area>
<Name>RA 001</Name>
<Desc/>
<Facility_Area>ZUF</Facility_Area>
</Area>
<Area>
<Name>RA 002</Name>
<Desc/>
<Facility_Area>ZUF</Facility_Area>
</Area>
<Area>
<Name>RA 003</Name>
<Desc/>
<Facility_Area>ZUF</Facility_Area>
</Area>
<Area>
<Name>RA 004</Name>
<Desc/>
<Facility_Area>ZUF</Facility_Area>
</Area>
...
</AreaCodes>
</Codes>

全部在一个文件中。

这是我有 atm 的 XSLT 模板:
<?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="facility" />
<xsl:param name="area" />


<!-- IDENTITY TRANSFORM -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<!-- Templates -->


<xsl:template match="Codes/AreaCodes/Area/Name">
<xsl:copy>
<xsl:value-of select="$area"/>
</xsl:copy>
</xsl:template>

<xsl:template match="Codes/AreaCodes/Area/Facility_Area">
<xsl:copy>
<xsl:value-of select="$facility"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

最后但并非最不重要的是 VBA 代码,其中所有内容都汇集在一起​​:
    Sub Param_XSLT_Process()

...

' LOAD XML AND XSL FILES
xmldoc.async = False
xmldoc.Load "Path\To\Vorlage_AREA.xml"

xslDoc.async = False
xslDoc.setProperty "AllowDocumentFunction", True
xslDoc.Load "Path\To\XSL_SHEET.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 "area", CStr(.Cells(lRow, 2).Value) ' ADD PARAMETER(S)
xslProc.addParameter "facility", CStr(.Cells(lRow, 1).Value)

xslProc.transform ' TRANSFORM XML
newDoc.LoadXML xslProc.output ' LOAD RESULT TREE
newDoc.Save "Path\To\Output_" & lRow - 1 & ".xml" ' SAVE OUTPUT TO FILE
Next lRow
End With
...
End Sub

现在,所有内容都放在一个单独的 XML 文件中。

谁能告诉我,我必须改变什么?我知道,对于我的 VBA 代码,我应该将那些保存命令移到循环之外,但这不起作用。

很抱歉在英语方面遇到了困难,感谢大家的帮助。

最佳答案

我写了一个VBA类模块SheetWrapper :

Private mySheet As Object

Sub Init(sheet)
Set mySheet = sheet
End Sub

Public Property Get Cell(rowIndex, cellIndex)
Cell = CStr(mySheet.Cells(rowIndex, cellIndex).Value)
End Property

然后就可以使用
Sub Param_XSLT_Process()
Dim xmlDoc As New MSXML2.DOMDocument60

Dim xslDoc As New MSXML2.FreeThreadedDOMDocument60

Dim xslTemp As New MSXML2.XSLTemplate60

Dim xslProc As MSXML2.IXSLProcessor

Dim resultDoc As New MSXML2.DOMDocument60

Dim worksheet As Object
Set worksheet = ActiveWorkbook.Worksheets(1)

Dim myWrapper As SheetWrapper
Set myWrapper = New SheetWrapper

myWrapper.Init worksheet


' LOAD XML AND XSL FILES
xmlDoc.async = False
xmlDoc.Load "C:\SomePath\template.xml"

xslDoc.async = False
xslDoc.SetProperty "AllowDocumentFunction", True
xslDoc.Load "C:\SomePath\sheet.xsl"

' INITIALIZE NEEDED OBJECTS
Set xslTemp.stylesheet = xslDoc
Set xslProc = xslTemp.createProcessor()

xslProc.addObject myWrapper, "http://example.com/excel"

xslProc.addParameter "first-row-index", 2, ""
xslProc.addParameter "last-row-index", ActiveWorkbook.Worksheets(1).UsedRange.Rows.Count, ""


xslProc.input = xmlDoc

xslProc.output = resultDoc

xslProc.transform

resultDoc.Save "C:\SomePath\transformation-result.xml"
End Sub

与 XSLT 一起:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:excel="http://example.com/excel"
exclude-result-prefixes="msxsl excel">

<xsl:param name="sheet"/>

<xsl:param name="first-row-index"/>
<xsl:param name="last-row-index"/>

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

<xsl:output indent="yes"/>

<xsl:template match="AreaCodes">
<xsl:copy>
<xsl:call-template name="make-areas">
<xsl:with-param name="area" select="Area"/>
<xsl:with-param name="index" select="$first-row-index"/>
<xsl:with-param name="last" select="$last-row-index"/>
</xsl:call-template>
</xsl:copy>
</xsl:template>

<xsl:template name="make-areas">
<xsl:param name="area"/>
<xsl:param name="index"/>
<xsl:param name="last"/>
<xsl:apply-templates select="$area">
<xsl:with-param name="row-index" select="$index"/>
</xsl:apply-templates>
<xsl:if test="$index &lt; $last">
<xsl:call-template name="make-areas">
<xsl:with-param name="area" select="$area"/>
<xsl:with-param name="index" select="$index + 1"/>
<xsl:with-param name="last" select="$last"/>
</xsl:call-template>
</xsl:if>
</xsl:template>

<xsl:template match="Area">
<xsl:param name="row-index"/>
<xsl:copy>
<xsl:apply-templates>
<xsl:with-param name="row-index" select="$row-index"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>

<xsl:template match="Area/Name">
<xsl:param name="row-index"/>
<xsl:copy>
<xsl:value-of select="excel:get-Cell($row-index, 1)"/>
</xsl:copy>
</xsl:template>

<xsl:template match="Area/Facility_Area">
<xsl:param name="row-index"/>
<xsl:copy>
<xsl:value-of select="excel:get-Cell($row-index, 2)"/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

我曾希望能够将 Excel 工作表对象直接传递给 XSLT 以读取其单元格,但不知何故 MSXML 并没有理解这一点。

关于excel - 如何更改此基于 VBA/XSLT 的代码,以便将输出写入单个 XML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57994607/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com