XmlWrap() Function

This convenience function helps you write more readable code when building Office Ribbon-flavored XML strings.

XmlWrap() Function

I use this convenience function to build custom ribbon XML.

I'm sure it could be used in other XML scenarios, but you have to be careful.  The function introduces whitespace for readability of the resulting XML.  This is not a problem for Office ribbon XML, as the whitespace is insignificant.  The same may not be true for other flavors of XML.

I use the term "convenience function" to refer to simple functions that don't necessarily save you any lines of code, but that make your existing code easier to read.  

Office Ribbon XML

Here's a sample of some ribbon XML from the Microsoft documentation:

Notice in the above screenshot how there is no XML content; everything is either a start tag, an end tag, or an empty element tag (e.g., <group idMso="GroupFont" visible="false" />).  This is why we don't have to worry about whitespace impacting the functionality of our ribbon XML.  

As a result, we can safely use whitespace as we see fit to generate more human-readable XML markup.

Benefits of the XmlWrap() Function

Let's look at two different ways to generate the following text:

The first Xml = line shows how to create the above text with basic string concatenation.  The second Xml = uses my XmlWrap() function instead.

Const InnerXml As String = "<group idMso=""GroupFont"" visible=""false"" />"


Xml = "<tab idMso=""TabHome"">" & vbNewLine & _
      vbTab & InnerXml & vbNewLine & _
      "</tab>"     

' vs.

Xml = XmlWrap(InnerXml, "tab", "idMso=""TabHome""")

There are a few benefits to this function:

  • Guarantees that the opening and closing tags match
  • Avoids typos
  • Enforces consistent whitespace
  • Automatically creates an empty element tag if there is no text to wrap

These benefits become clearer when you begin to incorporate the function into a more complex scenario, such as my ribbon XML builder class module.

Sample Usage

If there is no content to wrap, the function saves space by creating an empty-element tag instead of opening and closing tags.

The Code

'>>> XmlWrap("", "elementName")
'<elementName />
'>>> XmlWrap("<innerNode/>", "elementName")
'<elementName>`n`t<innerNode/>`n</elementName>
'>>> XmlWRap("", "elementName", "font=""Arial""")
'<elementName font="Arial" />
Function XmlWrap(TxtToWrap As String, _
                 ElementName As String, _
                 Optional Attrs As String) As String
    Dim TagText As String
    TagText = Conc(ElementName, Attrs, " ")
    
    If Len(TxtToWrap) = 0 Then
        XmlWrap = "<" & TagText & " />"
    Else
        Dim IndentedTxtToWrap As String
        IndentedTxtToWrap = vbTab & Replace(TxtToWrap, vbNewLine, vbNewLine & vbTab)
        XmlWrap = "<" & TagText & ">" & vbNewLine & _
                  IndentedTxtToWrap & vbNewLine & _
                  "</" & ElementName & ">"
    End If
End Function

Dependencies

  • The Conc() function which I use to concatenate strings.
  • The usage examples shown in the '>>> comments are verifiable DocTests.

Referenced articles

Come Together
Do you build strings in loops? Stop trimming the delimiter at the end of the loop. There’s a better way.
Python-inspired Doc Tests in VBA
Doc tests are not a replacement for unit or integration testing. But they do provide the best return on investment (ROI) of any type of test, mostly because the effort to write them is near zero.

Image by donations welcome from Pixabay

UPDATE [2022-06-23]: Added Dependencies section with link to Conc() function article.

All original code samples by Mike Wolfe are licensed under CC BY 4.0