XML 到 XML XSLT 转换。 VBScript 中的 MSXML

XML to XML XSLT transformation. MSXML in VBScript

我有一个相当嵌套的 XML 文件,我想使用 XSL 模板将其转换为更简单的文件,以便更高效地将数据批量加载到 SQL 中。我想用 C++(Codeblocks with gcc)来做,但我遇到了一点麻烦,就是无法使用我遇到的任何库(包括 MSXML)加载文档。如果有人有在 Codeblocks 中使用 MSXML 和 gcc 的经验,请告诉我!

我有一个样式sheet,它使用 DOMDocument 转换 Excel VBA 中的 XML,但我不想依赖 Excel .我认为下一个最好的东西是 VBScript。

数据是保存在 <DATAVALUE> 个节点中的一两个文本值,这些节点是 100 个 <LOCATION> 节点的后代。每个 <LOCATION> 节点的第一个 child,称为 <LOCATIONNAME>,为每个 <LOCATION> 节点保存一个唯一的名称(即 NAME1-NAME100) . <LOCATION>节点的第三个和第四个children(如果有第四个child)是<DATA>个节点,每个节点持有一个<DATAVALUE>个节点。该文件可以有超过 100 万个 <SAMPLE> 个节点。这是 XML:

<?xml version="1.0" encoding="utf-8"?>
<MYImportFile xmlns="urn:ohLookHEREaNamespacedeclaration">
  <HEADERVERSION>1.10</HEADERVERSION>
  <MESSAGE>Import</MESSAGE>
  <MYBED>QUEEN</MYBED>
  <SOURCE>SPRING </SOURCE>
  <USERID>MMOUSE</USERID>
  <DATETIME>2019-11-25T12:31:00</DATETIME>
  <SAMPLE TYPE="No" APPLE="false">
    <SAMPLEID>0000565</SAMPLEID>
    <SAMPLECATEGORY>CLASS5</SAMPLECATEGORY>
    <LOCATION APPLE="false">
      <LOCATIONNAME>NAME1</LOCATIONNAME>
      <READBY>MMOUSE</READBY>
      <TIME>12:31:00</TIME>
      <DATA>
        <DATAVALUE>aaaa</DATAVALUE>
      </DATA>
      <DATA>
        <DATAVALUE>bbbb</DATAVALUE>
      </DATA>
    </LOCATION>
    '''''''''''''''''there are 100 LOCATION entries''''''''''''''''''''''''
    <LOCATION APPLE="false">
      <LOCATIONNAME>NAME100</LOCATIONNAME>
      <READBY>MMOUSE</READBY>
      <TIME>12:31:00</TIME>
      <DATA>
        <DATAVALUE>zzzz</DATAVALUE>
      </DATA>
    </LOCATION>
  </SAMPLE>
  '''''''''''''''''repeat for however many SAMPLES there are''''''''''''''''''''''
</MYImportFile>

我想指出一些事情,以便更清楚地了解发生了什么。在转换后的 xml 文档中,我需要考虑的一件事是 <LOCATION> 中只有一个 <DATA> 节点。这是通过将第一个 <DATAVALUE> 节点复制到新文档中的第二个 <DATAVALUE> 节点来完成的。例如,在转换后的sheet中出现两次的<DATAVALUE>"zzzz"只在初始的XML中出现一次。这是我希望转换后的 XML 的样子:

<?xml version="1.0" encoding="UTF-8"?>
<MYImportFile>
    <SAMPLE>
        <SAMPLEID>0000565</SAMPLEID>
        <NAME1_1>aaaa</NAME1_1>
        <NAME1_2>bbbb</NAME1_2>
        <NAME2_1>cccc</NAME2_1>
        <NAME2_2>dddd</NAME2_2>
        '''''''''''''''''there are 100 LOCATION entries transformed to NAME1-NAME100''''''''''''''''''''''''
        <NAME100_1>zzzz</NAME100_1>
        <NAME100_2>zzzz</NAME100_2>
    </SAMPLE>
    '''''''''''''''''repeat for however many SAMPLES there are''''''''''''''''''''''
</MYImportFile>

我的样式表(适用于 VBA 代码):

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:b="urn:ohLookHEREaNamespacedeclaration" exclude-result-prefixes="b">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/b:MYImportFile">

<MYImportFile>

    <xsl:for-each select="b:SAMPLE">

    <SAMPLE>

        <SAMPLEID>
        <xsl:value-of select="b:SAMPLEID"/>
        </SAMPLEID>

        <NAME1_1>
        <xsl:value-of select="b:LOCATION/b:LOCATIONNAME[text() = 'NAME1']/../b:DATA[1]/b:DATAVALUE"/>
        </NAME1_1>

        <xsl:choose> 
            <xsl:when test="b:LOCATION/b:LOCATIONNAME[text() = 'NAME1']/../b:DATA[2]/b:DATAVALUE">
                <NAME1_2>
                <xsl:value-of select="b:LOCATION/b:LOCATIONNAME[text() = 'NAME1']/../b:DATA[2]/b:DATAVALUE"/>
                </NAME1_2>
            </xsl:when>
            <xsl:otherwise>
                <NAME1_2>
                <xsl:value-of select="b:LOCATION/b:LOCATIONNAME[text() = 'NAME1']/../b:DATA[1]/b:DATAVALUE"/>
                </NAME1_2>
            </xsl:otherwise>
        </xsl:choose>


        '''''''''''''''''''there are 100 NAME entires to recieve the 100 locations

    </SAMPLE>

    </xsl:for-each>

</MYImportFile>

</xsl:template>
</xsl:stylesheet>

我的脚本:

Option Explicit

Const strInputFile = "C:\Path\fileName.xml"
Const strTemplateFile = "C:\Path\convFileName.xsl"
Const strOutputFile = "C:\Path\newFileName.xml"

Dim objXMLDoc : Set objXMLDoc = WScript.CreateObject("Msxml2.DOMDocument")
objXMLDoc.async = False
objXMLDoc.loadXML(strInputFile)

objXMLDoc.SetProperty "SelectionNamespaces", "xmlns='urn:myNamespace'"

Dim objXSLDoc : Set objXSLDoc = WScript.CreateObject("Msxml2.DOMDocument")
objXSLDoc.async = False
objXSLDoc.loadXML(strTemplateFile)


Dim objNewXMLDoc : Set objNewXMLDoc = WScript.CreateObject("Msxml2.DOMDocument")

objXMLDoc.transformNodeToObject objXSLDoc, objNewXMLDoc 
objNewXMLDoc.save strOutputFile

错误:

Line: 19

Char: 1

Error: The stylesheet does not contain a document element. The stylesheet may be empty, or it may not be a well-formed XML document.

Code: 80004005

Source: msxml3.dll

我猜要么是我的脚本不太正确,要么是我缺少某个设置,导致 objects 和库不匹配,因为我的 VBA 宏转换了 xml 那种风格sheet。有人有主意吗?做这个东西的建议运行?

据我所知,loadXML 接受带有 XML 的字符串。如果您有文件或 URL 需要解析,请使用 load 方法。