XML到XML XSLT转换。 VBScript中的MSXML

问题描述 投票:0回答:1

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

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

数据是<DATAVALUE>节点中保留的一个或两个文本值,是100个<LOCATION>节点的后代。每个<LOCATION>节点的第一个子节点称为<LOCATIONNAME>,为每个<LOCATION>节点保留唯一的名称(即NAME1-NAME100)。 <LOCATION>节点的第三和第四子节点(如果有第四子节点)是<DATA>节点,每个节点都拥有<DATAVALUE>节点。该文件最多可以有100万个<SAMPLE>节点。这是XML:

<?xml version="1.0" encoding="utf-8"?>
<MYImportFile xmlns="urn:myNamespace">
  <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文档中,我需要考虑的一件事是<DATA>中只有一个<LOCATION>节点时。这是通过将第一个<DATAVALUE>节点复制到新文档中的第二个<DATAVALUE>节点来完成的。例如,在转换后的工作表中出现两次的<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:myNamespace" 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

错误:

第19行

字符:1

错误:样式表不包含文档元素。的样式表可能为空,或者可能不是格式正确的XML文档。

代码:80004005

来源:msxml3.dll

我猜我的脚本不是很正确,或者我缺少某个设置,导致对象和库不匹配,因为我的VBA宏使用该样式表转换了xml。有人有想法么?建议使此事情运行?

c++ xml xslt vbscript msxml
1个回答
1
投票

据我记得,loadXML使用XML字符串。如果您有要解析的文件或URL,请使用load方法。

© www.soinside.com 2019 - 2024. All rights reserved.