2

I am trying to generate an xml from a set of xpaths. This is related to Generating XML from xpath using xslt

I found a XSLT that may solve my problem in this answer to another question

<xsl:stylesheet version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:my="my:my">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>

     <xsl:key name="kNSFor" match="namespace" use="@of"/>
     <xsl:variable name="vStylesheet" select="document('')"/>

     <xsl:variable name="vPop" as="element()*">
        <item path="/create/article/@type">richtext</item>
        <item path="/create/article/@lang">en-us</item>
        <item path="/create/article[1]/id">1</item>
        <item path="/create/article[1]/description">bar</item>
        <item path="/create/article[1]/name[1]">foo</item>
        <item path="/create/article[1]/price[1]/amount">00.00</item>
        <item path="/create/article[1]/price[1]/currency">USD</item>
        <item path="/create/article[1]/price[2]/amount">11.11</item>
        <item path="/create/article[1]/price[2]/currency">AUD</item>
        <item path="/create/article[2]/id">2</item>
        <item path="/create/article[2]/description">some name</item>
        <item path="/create/article[2]/name[1]">some description</item>
        <item path="/create/article[2]/price[1]/amount">00.01</item>
        <item path="/create/article[2]/price[1]/currency">USD</item>

        <namespace of="create" prefix="ns1:"
                   url="http://predic8.com/wsdl/material/ArticleService/1/"/>
        <namespace of="article" prefix="ns1:"
                   url="xmlns:ns1='http://predic8.com/material/1/"/>
        <namespace of="@lang" prefix="xml:"
                   url="http://www.w3.org/XML/1998/namespace"/>
        <namespace of="price" prefix="ns1:"
                   url="xmlns:ns1='http://predic8.com/material/1/"/>
        <namespace of="id" prefix="ns1:"
                   url="xmlns:ns1='http://predic8.com/material/1/"/>
     </xsl:variable>

     <xsl:template match="/">
      <xsl:sequence select="my:subTree($vPop/@path/concat(.,'/',string(..)))"/>
     </xsl:template>

     <xsl:function name="my:subTree" as="node()*">
      <xsl:param name="pPaths" as="xs:string*"/>

      <xsl:for-each-group select="$pPaths" group-adjacent=
            "substring-before(substring-after(concat(., '/'), '/'), '/')">
        <xsl:if test="current-grouping-key()">
         <xsl:choose>
           <xsl:when test=
              "substring-after(current-group()[1], current-grouping-key())">

             <xsl:variable name="vLocal-name" select=
              "substring-before(concat(current-grouping-key(), '['), '[')"/>

             <xsl:variable name="vNamespace"
                           select="key('kNSFor', $vLocal-name, $vStylesheet)"/>


             <xsl:choose>
              <xsl:when test="starts-with($vLocal-name, '@')">
               <xsl:attribute name=
                 "{$vNamespace/@prefix}{substring($vLocal-name,2)}"
                    namespace="{$vNamespace/@url}">
                 <xsl:value-of select=
                  "substring(
                       substring-after(current-group(), current-grouping-key()),
                       2
                             )"/>
               </xsl:attribute>
              </xsl:when>
              <xsl:otherwise>
               <xsl:element name="{$vNamespace/@prefix}{$vLocal-name}"
                          namespace="{$vNamespace/@url}">

                    <xsl:sequence select=
                     "my:subTree(for $s in current-group()
                                  return
                                     concat('/',substring-after(substring($s, 2),'/'))
                                   )
                     "/>
                 </xsl:element>
              </xsl:otherwise>
             </xsl:choose>
           </xsl:when>
           <xsl:otherwise>
            <xsl:value-of select="current-grouping-key()"/>
           </xsl:otherwise>
         </xsl:choose>
         </xsl:if>
      </xsl:for-each-group>
     </xsl:function>
</xsl:stylesheet>

I am trying to transform this in VBA using code from http://www.oreillynet.com/xml/blog/2005/04/transforming_xml_in_microsoft.html

I got an error
error when using transformNodeToObject

Private Sub Transform(sourceFile, stylesheetFile, resultFile)

    Dim source As New MSXML2.DOMDocument30
    Dim stylesheet As New MSXML2.DOMDocument30
    Dim result As New MSXML2.DOMDocument30

    ' Load data.
    source.async = False
    source.Load sourceFile

    ' Load style sheet.
    stylesheet.async = False
    stylesheet.Load stylesheetFile

    If (source.parseError.ErrorCode <> 0) Then
       MsgBox ("Error loading source document: " & source.parseError.reason)
    Else
        If (stylesheet.parseError.ErrorCode <> 0) Then
            MsgBox ("Error loading stylesheet document: " & stylesheet.parseError.reason)
        Else
            ' Do the transform.
            source.transformNodeToObject stylesheet, result
            result.Save resultFile
        End If
    End If

End Sub

I also tried to use transformNode instead to transformNodeToObject. I got

object doesn't support this property or method

transformNode error

Private Sub Transform(sourceFile, stylesheetFile, resultFile)
    Dim source As New MSXML2.DOMDocument60
    Dim stylesheet As New MSXML2.DOMDocument60
    Dim result As New MSXML2.DOMDocument60

    ' Load data
    source.async = False
    source.Load sourceFile

    ' Load style sheet.
    stylesheet.async = False
    stylesheet.Load stylesheetFile

    If (source.parseError.ErrorCode <> 0) Then
       MsgBox ("Error loading source document: " & source.parseError.reason)
       Else
    If (stylesheet.parseError.ErrorCode <> 0) Then
          MsgBox ("Error loading stylesheet document: " & stylesheet.parseError.reason)
       Else
          ' Do the transform.
          source.transformNode (stylesheet)
          'result.Save resultFile
    End If
    End If
End Sub
Community
  • 1
  • 1
Abhishek Asthana
  • 1,857
  • 1
  • 31
  • 51
  • 1
    It seems to me you are using MSXSL - right? It supports only XSLT 1.0 - so any XSLT 2.0 functionality will not work. See for example: http://msdn.microsoft.com/en-us/library/ms757858%28v=vs.85%29.aspx , especially the last question at the bottom of the page – Mathias Müller Mar 13 '14 at 15:06
  • 1
    Well one problem is certainly that all MSXML versions only support XSLT 1.0 while your XSLT is XSLT 2.0 and makes heavy use of features only supported in that version of the language and by XSLT 2.0 processors. So using MSXML with XSLT 2.0 and things like `for-each-group` is not going to work. – Martin Honnen Mar 13 '14 at 15:08
  • Great there goes that out of the window..Thanks guys. – Abhishek Asthana Mar 13 '14 at 15:24
  • Perhaps you should take a stab at writing the XSLT using 1.0 so you can run it within your limitation of using VB – Kevin Brown Mar 13 '14 at 20:36
  • @KevinBrown I do not know how to write xslt...and given my time limitation i would rather work on other aspects of my problem.. i actually asked for help with xslt on another question http://stackoverflow.com/questions/22353758/generating-xml-from-xpath-using-xslt – Abhishek Asthana Mar 14 '14 at 01:35
  • @MathiasMüller I am using MSXML but as MartinHonnen pointed out..that also doesn't support XSLT 2.0 – Abhishek Asthana Mar 14 '14 at 18:47
  • That is what I meant - sorry for the typo. – Mathias Müller Mar 14 '14 at 18:58

0 Answers0