* this is just a subset of the line, just complete with the rest CREATE CURSOR xlsOutput (InvoiceNo Varchar(32), SystemEntryDate Datetime, ; productCode Varchar(50), productDescription Varchar(200), ; taxpayable Double, grosstotal Double) LOCAL XML AS MSXML2.DOMDocument60 m.XML = CREATEOBJECT("MSXML2.DOMDocument.6.0") m.XML.Async = .F. m.XML.Load(GETFILE()) LOCAL Invoices AS MSXML2.IXMLDOMNodeList LOCAL Invoice AS MSXML2.IXMLDOMNode LOCAL DocTotals AS MSXML2.IXMLDOMNode LOCAL Details AS MSXML2.IXMLDOMNodeList LOCAL Detail AS MSXML2.IXMLDOMNode LOCAL FromHeader AS Object LOCAL FromTotals AS Object LOCAL FromDetail AS Object m.XML.Setproperty("SelectionNamespaces", 'xmlns:saft="urn:OECD:StandardAuditFile-Tax:PT_1.04_01"') m.Invoices = m.XML.Selectnodes("//saft:SourceDocuments/saft:SalesInvoices/saft:Invoice") FOR EACH m.Invoice IN m.Invoices XMLTOCURSOR("<vfp>" + m.Invoice.xml + "</vfp>", "tmpInvoiceHeader") SCATTER NAME FromHeader m.DocTotals = m.Invoice.selectNodes("saft:DocumentTotals").item(0) XMLTOCURSOR("<vfp>" + m.DocTotals.xml + "</vfp>", "tmpInvoiceTotals") SCATTER NAME FromTotals m.Details = m.Invoice.selectNodes("saft:Line") FOR EACH m.Detail IN m.Details XMLTOCURSOR("<vfp>" + m.Detail.xml + "</vfp>", "tmpInvoiceDetail") SCATTER NAME FromDetail SELECT xlsOutput APPEND BLANK GATHER NAME m.FromHeader GATHER NAME m.FromTotals GATHER NAME m.FromDetail ENDFOR ENDFOR SELECT xlsOutput BROWSETwo notes: if it was a probIem I was required to solve, I would transform the XML into a CSV file (or into an XML ready to be XMLTOCURSORed()), but that's because XLST is a kind of second skin for me (regardless of being the right tool for the job, as I see it). I believe it would be more difficult for you, so this approach that I suggested is easily adaptable to your requirements. I also tried to ingest the SAFT schema into an XMLAdapter object, but since it raise an error and I don't feel like to feed the XML 4.0 beast any longer, I swiftly gave up on that.