B4J Question [B4X] Xml2Map - read file xml

Roberto P.

Well-Known Member
Licensed User
Longtime User
Hi,
can anyone help me to read this simple xml file, Italian Cityes, that is making me waste a lot of time?

<?xml version="1.0" encoding="utf-8"?>
<Auxdata>
<Header>
<Fieldtype name="City" key="1" hidden="0" type="string" />
<Fieldtype name="County" key="0" hidden="1" type="string" />
<Fieldtype name="ZIPCode" key="0" hidden="1" type="string" />
<Fieldtype name="Region" key="0" hidden="1" type="string" />
</Header>
<Elements>
<Element>
<Field name="City">Agrigento</Field>
<Field name="County">AG</Field>
<Field name="ZIPCode">92100</Field>
<Field name="Region">Sicilia</Field>
</Element>
<Element>
<Field name="City">Alessandria</Field>
<Field name="County">AL</Field>
<Field name="ZIPCode">15100</Field>
<Field name="Region">Piemonte</Field>
</Element>
<Element>
<Field name="City">Ancona</Field>
<Field name="County">AN</Field>
<Field name="ZIPCode">60100</Field>
<Field name="Region">Marche</Field>
</Element>

B4X:
Dim aux As Map             = ParsedData.Get("Auxdata")
    Dim elements As Map     = aux.Get("Elements")
    Dim items As List         = elements.Get("Element")
    

    
    For i = 0 To items.Size -1
        
        Dim aField As Map = items.Get(i)
        
        For r=0 To aField.Size - 1
                    
            Dim aValues As List    = aField.GetValueAt(r)
            
            
            For z = 0 To aValues.Size -1
                Dim aData As Map = aValues.Get(z)
                                
                For z1 = 0 To aData.Size -1
                    Log(aData.GetKeyAt(z1) & " - " & aData.GetValueAt(z1))
                Next
                
            Next
            
        Next
        
    Next

I would like to read the values of the individual fields in this way:

B4X:
For Each item As Map In items
        Dim City As String = item.Get("City")
        Dim County As String = item.Get("County")
        Dim ZIPCode As String = item.Get("ZIPCode")
        Dim Region As String = item.Get("Region")
    Next

Thank in advance
regards
 

DonManfred

Expert
Licensed User
Longtime User
Use xml2map
 
Upvote 0

Roberto P.

Well-Known Member
Licensed User
Longtime User
Use xml2map

My example use it:


B4X:
Dim xm As Xml2Map
    xm.Initialize
    Dim ParsedData As Map = xm.Parse(File.ReadString(File.DirApp & "/" & mFolderDownload, "cyty.xml"))
 
Upvote 0

Roberto P.

Well-Known Member
Licensed User
Longtime User
Code that uses GetKeyAt / GetValueAt is considered broken code.

You should upload a small project with the XML file and your code.

attached. Thank you
 

Attachments

  • textxml.zip
    1.4 KB · Views: 333
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I like to use JsonGenerator for such cases:
B4X:
Dim aux As Map = ParsedData.Get("Auxdata")
Dim jg As JSONGenerator
jg.Initialize(aux)
Log(jg.ToPrettyString(4))
1. The logs will help you understand the structure.
2. You can copy the json output to this tool: https://b4x.com:51041/json/index.html
It will give you the code that you need in order to parse it.
 
Upvote 0

Roberto P.

Well-Known Member
Licensed User
Longtime User
I like to use JsonGenerator for such cases:
B4X:
Dim aux As Map = ParsedData.Get("Auxdata")
Dim jg As JSONGenerator
jg.Initialize(aux)
Log(jg.ToPrettyString(4))
1. The logs will help you understand the structure.
2. You can copy the json output to this tool: https://b4x.com:51041/json/index.html
It will give you the code that you need in order to parse it.

it is not clear to me why you have to read xml and convert to Json, but it works!

the best tool!
thank you
 
Upvote 0

Roberto P.

Well-Known Member
Licensed User
Longtime User
I hope it is useful to summarize the steps to get the result:

1: Read file xml in Map

B4X:
Dim xm As Xml2Map
    xm.Initialize
    Dim ParsedData As Map = xm.Parse(File.ReadString(File.DirApp & "/" & mFolderDownload, "State.xml"))

2:parser map to JSon

B4X:
Dim JG As JSONGenerator
JG.Initialize(ParsedData)
Log(JG.ToPrettyString(4))

3:copy log: copy all toclipboard

4: paste in web tools https://b4x.com:51041/json/index.html and generate members

B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim Auxdata As Map = root.Get("Auxdata")
Dim Header As Map = Auxdata.Get("Header")
Dim Fieldtype As List = Header.Get("Fieldtype")
For Each colFieldtype As Map In Fieldtype
 Dim Attributes As Map = colFieldtype.Get("Attributes")
 Dim hidden As String = Attributes.Get("hidden")
 Dim name As String = Attributes.Get("name")
 Dim type As String = Attributes.Get("type")
 Dim key As String = Attributes.Get("key")
 Dim Text As String = colFieldtype.Get("Text")
Next
Dim Elements As Map = Auxdata.Get("Elements")
Dim Element As List = Elements.Get("Element")
For Each colElement As Map In Element
 Dim Field As List = colElement.Get("Field")
 For Each colField As Map In Field
  Dim Attributes As Map = colField.Get("Attributes")
  Dim name As String = Attributes.Get("name")
  Dim Text As String = colField.Get("Text")
 Next
Next

5: remove JSon parser and use first map
B4X:
Private Sub ImportStates
    Dim xm As Xml2Map
    xm.Initialize
    Dim ParsedData As Map = xm.Parse(File.ReadString(File.DirApp & "/" & mFolderDownload, "State.xml"))
    
    Dim Auxdata As Map = ParsedData.Get("Auxdata")
    Dim Header As Map = Auxdata.Get("Header")
    Dim Fieldtype As List = Header.Get("Fieldtype")
    For Each colFieldtype As Map In Fieldtype
        Dim Attributes As Map = colFieldtype.Get("Attributes")
        Dim hidden As String = Attributes.Get("hidden")
        Dim name As String = Attributes.Get("name")
        Dim Type As String = Attributes.Get("type")
        Dim key As String = Attributes.Get("key")
        Dim Text As String = colFieldtype.Get("Text")
    Next
    Dim Elements As Map = Auxdata.Get("Elements")
    Dim Element As List = Elements.Get("Element")
    For Each colElement As Map In Element
        Dim Field As List = colElement.Get("Field")
        For Each colField As Map In Field
            Log("--------")
            Dim Attributes As Map = colField.Get("Attributes")
            Dim name As String = Attributes.Get("name")
            Dim Text As String = colField.Get("Text")
            
            Log("Name = " & name & " " & Text)
            
        Next
    Next
    
End Sub
 
Upvote 0
Top