<?xml version="1.0" encoding="utf-8" ?> <root> <Header Sender='CompanyA' Recipient='CompanyB'/> <Detail Trailer_ID='3545452355454234' Lorry_ID='1523445532'/> <Detail Trailer_ID='4444442355454234' Lorry_ID='5555545532'/> </root>
CLOSE DATABASES all clear TEXT TO cXml NOSHOW <?xml version="1.0" encoding="utf-8" ?> <root> <Header Sender='CompanyA' Recipient='CompanyB'/> <Detail Trailer_ID='3545452355454234' Lorry_ID='1523445532'/> <Detail Trailer_ID='4444442355454234' Lorry_ID='5555545532'/> </root> ENDTEXT LOCAL oXA as XMLAdapter, oXT as XMLTable, oXF as XMLField oXA=CREATEOBJECT("XMLAdapter") oXA.LoadXML(cXml) * create XMLTable object for the first table oXT=CREATEOBJECT("XMLTable") oXT.XMLName=STRCONV("Header",5) oXT.Alias="Header" oXA.Tables.Add(oXT,oXT.XMLName) oXF=CREATEOBJECT("XMLField") oXF.XMLName=STRCONV("Sender",5) oXF.IsAttribute= .T. oXF.Alias="Sender" oXF.DataType="C" oXF.MaxLength=10 oXT.Fields.Add(oXF,oXF.XMLName) oXF=CREATEOBJECT("XMLField") oXF.XMLName=STRCONV("Recipient",5) oXF.IsAttribute= .T. oXF.Alias="Recipient" oXF.DataType="C" oXF.MaxLength=10 oXT.Fields.Add(oXF,oXF.XMLName) * create XMLTable object for the second table oXT=CREATEOBJECT("XMLTable") oXT.XMLName=STRCONV("Detail",5) oXT.Alias="Detail" oXA.Tables.Add(oXT,oXT.XMLName) oXF=CREATEOBJECT("XMLField") oXF.XMLName=STRCONV("Trailer_ID",5) oXF.IsAttribute= .T. oXF.Alias="Trailer_ID" oXF.DataType="C" oXF.MaxLength=20 oXT.Fields.Add(oXF,oXF.XMLName) oXF=CREATEOBJECT("XMLField") oXF.XMLName=STRCONV("Lorry_ID",5) oXF.IsAttribute= .T. oXF.Alias="Lorry_ID" oXF.DataType="C" oXF.MaxLength=10 oXT.Fields.Add(oXF,oXF.XMLName) FOR EACH oXT IN oXA.Tables ?oXT.ToCursor() SELECT (oXT.Alias) ?ALIAS() LIST NEXT returnThe same code will work for XML like this.
<?xml version="1.0" encoding="utf-8" ?> <root> <Header Sender='CompanyA' Recipient='CompanyB'> <Detail Trailer_ID='3545452355454234' Lorry_ID='1523445532'/> <Detail Trailer_ID='4444442355454234' Lorry_ID='5555545532'/> </Header> </root>But with this XML you can instruct XMLAdapter to join these tables by using XMLTable.ChildTable property:
CLOSE DATABASES all clear TEXT TO cXml NOSHOW <?xml version="1.0" encoding="utf-8" ?> <root> <Header Sender='CompanyA' Recipient='CompanyB'> <Detail Trailer_ID='3545452355454234' Lorry_ID='1523445532'/> <Detail Trailer_ID='4444442355454234' Lorry_ID='5555545532'/> </Header> </root> ENDTEXT LOCAL oXA as XMLAdapter, oXT as XMLTable, oXF as XMLField oXA=CREATEOBJECT("XMLAdapter") oXA.LoadXML(cXml) * create XMLTable object for the first table oXT=CREATEOBJECT("XMLTable") oXT.XMLName=STRCONV("Header",5) oXA.Tables.Add(oXT,oXT.XMLName) oXF=CREATEOBJECT("XMLField") oXF.XMLName=STRCONV("Sender",5) oXF.IsAttribute= .T. oXF.Alias="Sender" oXF.DataType="C" oXF.MaxLength=10 oXT.Fields.Add(oXF,oXF.XMLName) oXF=CREATEOBJECT("XMLField") oXF.XMLName=STRCONV("Recipient",5) oXF.IsAttribute= .T. oXF.Alias="Recipient" oXF.DataType="C" oXF.MaxLength=10 oXT.Fields.Add(oXF,oXF.XMLName) * create XMLTable object for the second table oXT=CREATEOBJECT("XMLTable") oXT.XMLName=STRCONV("Detail",5) oXA.Tables(1).ChildTable=oXT && <== this is the interesting part oXF=CREATEOBJECT("XMLField") oXF.XMLName=STRCONV("Trailer_ID",5) oXF.IsAttribute= .T. oXF.Alias="Trailer_ID" oXF.DataType="C" oXF.MaxLength=20 oXT.Fields.Add(oXF,oXF.XMLName) oXF=CREATEOBJECT("XMLField") oXF.XMLName=STRCONV("Lorry_ID",5) oXF.IsAttribute= .T. oXF.Alias="Lorry_ID" oXF.DataType="C" oXF.MaxLength=10 oXT.Fields.Add(oXF,oXF.XMLName) ?oXA.Tables(1).ToCursor(.F.,"Header_Detail") SELECT Header_Detail ?ALIAS() LIST returnDetail could also have a ChildTable. There are many interesting things you can do with XMLAdapter.