-1

I need XML files created by VBA to contain "<" in a string. Currently VBA turns all instances of "<" into "&It;" as this characters is used for tags.

I believe something needs to added towards the end of the code to find and replace all instances of "&It;" to "<".

My Code

sTemplateXML = _
        " <movie>" + vbNewLine + _
        "   <plot/>" + vbNewLine + _
        "   <_outline/>" + vbNewLine + _
        "   <_lockdata/>" + vbNewLine + _
        "   <dateadded/>" + vbNewLine + _
        "   <title/>" + vbNewLine + _
        "   <rating/>" + vbNewLine + _
        "   <year/>" + vbNewLine + _
        "   <sorttile/>" + vbNewLine + _
        "   <mpaa/>" + vbNewLine + _
        "   <premiered/>" + vbNewLine + _
        "   <releasedate/>" + vbNewLine + _
        "   <runtime/>" + vbNewLine + _
        "   <studio/>" + vbNewLine + _
        "   <tag/>" + vbNewLine + _
        "   <actor/>" + vbNewLine + _
        " </movie>" + vbNewLine


 Set doc = CreateObject("MSXML2.DOMDocument")
 doc.async = False
 doc.validateOnParse = False
 doc.resolveExternals = False

With Sheets("Sheet3")
  lLastRow = .UsedRange.Rows.Count

 For lRow = 3 To lLastRow
   sFolder = .Cells(lRow, 677).Value
   sFile = .Cells(lRow, 678).Value
   sPlot = .Cells(lRow, 679).Value
   s_outline = .Cells(lRow, 680).Value
   s_lockdata = .Cells(lRow, 681).Value
   sDateadded = .Cells(lRow, 682).Value
   sTitle = .Cells(lRow, 683).Value
   sRating = .Cells(lRow, 684).Value
   sYear = .Cells(lRow, 685).Value
   sSorttile = .Cells(lRow, 686).Value
   sMpaa = .Cells(lRow, 687).Value
   sPremiered = .Cells(lRow, 688).Value
   sReleasedate = .Cells(lRow, 689).Value
   sRuntime = .Cells(lRow, 690).Value
   sStudio = .Cells(lRow, 691).Value
   sTag = .Cells(lRow, 692).Value
   sActor = .Cells(lRow, 693).Value

   doc.LoadXML sTemplateXML
   doc.getElementsByTagName("plot")(0).appendChild doc.createTextNode(sPlot)
   doc.getElementsByTagName("_outline")(0).appendChild doc.createTextNode(s_outline)
   doc.getElementsByTagName("_lockdata")(0).appendChild doc.createTextNode(s_lockdata)
   doc.getElementsByTagName("dateadded")(0).appendChild doc.createTextNode(sDateadded)
   doc.getElementsByTagName("title")(0).appendChild doc.createTextNode(sTitle)
   doc.getElementsByTagName("rating")(0).appendChild doc.createTextNode(sRating)
   doc.getElementsByTagName("year")(0).appendChild doc.createTextNode(sYear)
   doc.getElementsByTagName("sorttile")(0).appendChild doc.createTextNode(sSorttile)
   doc.getElementsByTagName("mpaa")(0).appendChild doc.createTextNode(sMpaa)
   doc.getElementsByTagName("premiered")(0).appendChild doc.createTextNode(sPremiered)
   doc.getElementsByTagName("releasedate")(0).appendChild doc.createTextNode(sReleasedate)
   doc.getElementsByTagName("runtime")(0).appendChild doc.createTextNode(sRuntime)
   doc.getElementsByTagName("studio")(0).appendChild doc.createTextNode(sStudio)
   doc.getElementsByTagName("tag")(0).appendChild doc.createTextNode(sTag)
   doc.getElementsByTagName("actor")(0).appendChild doc.createTextNode(sActor)
   doc.Save sFolder & sFile & ".nfo"
  Next
 
 End With

I've tried

  • strXml = VBA.Replace(strXml, "&", "&") {before doc.save - no errors but nothing is corrected}

I've found examples of functions (How to write an ampersand to an XML file from an Excel file using VBA?) but I have no idea where to place the code.

I've updated my post to address the criticsms below.

5
  • I think you can show the <>s by wrapping them in backticks: <name>Family member</name>. Commented May 23, 2021 at 22:03
  • 1
    What do you mean by "export"? Are you using SaveAsXMLData? A little more detail would help ;) Commented May 23, 2021 at 22:06
  • With the help of others here, I created a macro that creates XML files from each row stackoverflow.com/questions/67650954/… - everything works, I just need a way to display "<" in the outputed files. Commented May 23, 2021 at 22:15
  • to wazz - I just tried that but it still exports it the same Commented May 23, 2021 at 22:20
  • It doesn't do any good to point us to some other post's code, because we can't see how you're using it. Also, your XML is formed poorly - < name > should not include the spaces, but should be <name>. The incorrect spaces may be causing the element to be interpreted as text rather than XML. Commented May 24, 2021 at 0:05

1 Answer 1

1

I think the problem is that sActor contains tags so createTextNode(sActor) will encode the <'s. Unless you have some other reason to use MSXML2 objects I would suggest removing the tags from the data and building the xml more simply, for example

Sub CreateXMLfiles()

    Dim wb As Workbook, ws As Worksheet
    Dim tags, ar, t
    Dim iLastRow As Long, r As Long, n As Long
    Dim c As Integer, i As Integer, k As Integer
    Dim sFolder As String, sFile As String, s As String

    Dim fso, ts
    Set fso = CreateObject("Scripting.FilesystemObject")

    tags = Array("plot:679", "_outline:680", "_lockdata:681", "dateadded:682", "title:683", _
                "rating:684", "year:685", "sorttitle:686", "mpaa:687", "premiered:688", _
                "releasedate:689", "runtime:690", "studio:691", "tag:692", "actor,name:693")

    Set wb = ThisWorkbook
    Set ws = wb.Sheets("Sheet3")
    iLastRow = ws.UsedRange.Row + ws.UsedRange.Rows.Count - 1

    For r = 3 To iLastRow
        sFolder = wb.Path & "\" & ws.Cells(r, 677).Value & "\"
        sFile = ws.Cells(r, 678).Value
        If Len(sFile) > 0 Then
            s = "<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>" _
                & vbLf & "<movie>" & vbLf
            For i = 0 To UBound(tags)
                ar = Split(tags(i), ":") 'tag,column
                c = ar(1) ' data column
                t = Split(ar(0), ",") ' tree
                s = s & Space(4)
                For k = 0 To UBound(t)
                    s = s & "<" & t(k) & ">"
                Next
                s = s & ws.Cells(r, c) ' value
                For k = UBound(t) To 0 Step -1
                    s = s & "</" & t(k) & ">"
                Next
                s = s & vbLf
            Next
            s = s & "</movie>"
            
            ' save to file
            Set ts = fso.createTextFile(sFolder & sFile & ".nfo", 1, 1) ' overwrite, unicode
            ts.write s
            ts.Close
            n = n + 1
         End If
    Next
    MsgBox n & " files created in " & sFolder, vbInformation

End Sub
Sign up to request clarification or add additional context in comments.

10 Comments

@game you need to change wb.Sheets("Sheet1") to whatever your sheet is, looks like it should be Sheet3
@Game The tag names are in the array together with their column number "title:683"
@Game Thats OK, I have updated my answer to put files relative to workbook folder and skip those lines without a valid filename.
@game Change fso.createTextFile(sFolder & sFile & ".nfo", 1, 1) to fso.createTextFile(sFolder & sFile & ".nfo", 1, 0) . The 1 signifies Unicode encoding. White space in XML files shouldn't matter.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.