XML extractor App
Mix.install([
{:kino, "~> 0.17.0"},
{:sweet_xml, "~> 0.7.5"}
])
Section
IDEx XML Extractor
This app extracts the important information retreived from Diagnostics output from IDEx tool
defmodule FileHandler do
def get() do
Kino.Input.file("Upload your file", accept: ~w(.xml))
end
def read(file_ref) do
path = Kino.Input.file_path(file_ref)
%{path: path, content: File.read!(path)}
end
end
defmodule Ecu do
@enforce_keys [:id]
defstruct id: "",
swv: ""
end
defmodule User do
defstruct name: "",
client: "",
file: "",
time: "",
date: ""
def to_string(user) do
"""
### File:
#{user.file}
| User | PC Name| date| time|
| :---: | :---:| :---:| :---: |
| #{user.name} | #{user.client}| #{user.date} | #{user.time}|
"""
end
end
defmodule VehicleData do
defstruct km: 0,
vin: "",
name: ""
def to_string(vehicle) do
"""
| Name | VIN| Km|
| :---: | :---:| :---:|
| #{vehicle.name} | #{vehicle.vin}| #{vehicle.km} |
"""
end
end
defmodule XmlHandler do
import SweetXml
def getUser(content) do
%User{
name: content |> xpath(~x"//User/text()"S),
client: content |> xpath(~x"//ClientName/text()"S),
file: content |> xpath(~x"//Dateiname/text()"S),
time: content |> xpath(~x"//Zeit/text()"),
date: content |> xpath(~x"//Datum/text()")
}
end
def getVehicleData(content) do
%VehicleData{
vin: content |> xpath(~x"//Fahrgestellnummer/text()"S),
km: content |> xpath(~x"//WegStrecke/text()"i),
name: content |> xpath(~x"//UserProjekt/text()"S)
}
end
def getEcus(content) do
diagnostics =
content
|> xmap(
Diagnosebloecke: [
~x"//Diagnosebloecke/Diagnoseblock"l,
id: ~x"./Adresse/text()"S,
sw: ~x"./SWVersion/text()"S,
description: ~x"./Systembezeichnung/text()"S
]
)
Map.get(diagnostics, :Diagnosebloecke)
end
def getEcus(content, ids) do
diagList = getEcus(content)
a = Enum.map(ids, fn id -> Enum.filter(diagList, fn map -> map.id == id end) end)
List.flatten(a)
end
end
form =
Kino.Control.form(
[
file: FileHandler.get()
],
submit: "Parse"
)
outputFrame = Kino.Frame.new()
h1 =
Kino.HTML.new("""
IDEx XML Parser
This app helps you decode and extract the specific fields of the IDEx XML file.
""")
Kino.listen(form, fn event ->
%{data: %{file: %{file_ref: file_ref}}} = event
Kino.Frame.render(outputFrame, "Parsing XML...")
# {:file, validator} = file_ref
# if validator == "" do
# Kino.interrupt!(:error, "Please provide the XML file..")
# end
v = FileHandler.read(file_ref)
userDetails =
v.content
|> XmlHandler.getUser()
|> User.to_string()
|> Kino.Markdown.new()
vehicleDetails =
v.content
|> XmlHandler.getVehicleData()
|> VehicleData.to_string()
|> Kino.Markdown.new()
tabs =
Kino.Layout.tabs(
User: userDetails,
Vehicle: vehicleDetails,
Important_IDs:
Kino.DataTable.new(
XmlHandler.getEcus(v.content, ["0009", "0019", "8103", "8124", "812C"])
),
All_IDs: Kino.DataTable.new(XmlHandler.getEcus(v.content))
)
Kino.Frame.render(outputFrame, tabs)
end)
Kino.Layout.grid([h1, form, outputFrame])