If you use the XMLFragmenter with Elements to Match set to "feature" and flattening enabled you will end up with a key-value pair list for each feature
ex.
'attribuut{0}' has value `muur'
'attribuut{0}.naam' has value `type'
'attribuut{1}' has value `bestaad'
'attribuut{1}.naam' has value `IMGEO status'
You can then loop through the list and turn each element pair into an attribute.
ex with an attribute creator
@Value(attribuut{0}.naam) ; attribuut{0}
If on the other hand you want one feature per attribute you can set the fragmenter to attribuut and you will end up with attribuut = muur, attribuut.naam = type, and you can do the same thing without the list indexes.
I also think @jdh's solution is good enough, but, sorry, I cannot resist to try an XQuery solution...
Assuming the feature has an attribute called "xml_fragment" that stores an XML fragment. e.g.
<SHD>
<feature datadefinitie="Sleutels" code="SLEUTELS">
<attribuut naam="gisobjectnummeer">105963</attribuut>
</feature>
<feature datadefinitie="IMG" code="SHDV">
<attribuut naam="type">muur</attribuut>
<attribuut naam="IMGEO status">bestaand</attribuut>
<attribuut naam="In onderzoek">Nee</attribuut>
<attribuut naam="relatieveHoogteligging">0</attribuut>
<attribuut naam="identificatie">P0027.cdffbb11ae7c4f56a96af8f6c17cefb5</attribuut>
<attribuut naam="tijadstipRegistratie">20170626172844000</attribuut>
</feature>
<feature datadefinitie="GBK_LKI" code="C"></feature>
</SHD>
A JSONTemplater with this expression creates the following JSON object.JSONTemplater | Template Expression (XQuery expression)
let $x := fme:get-xml-attribute("xml_fragment")
let $members := {
for $a in $x//attribuut
return '"'||string($a/@naam)||'":"'||$a/text()||'"'
}
return '{'||fn:string-join($members, ',')||'}'
Resulting JSON Object:
{
"gisobjectnummeer" : "105963",
"type" : "muur",
"IMGEO status" : "bestaand",
"In onderzoek" : "Nee",
"relatieveHoogteligging" : "0",
"identificatie" : "P0027.cdffbb11ae7c4f56a96af8f6c17cefb5",
"tijadstipRegistratie" : "20170626172844000"
}
You can then extract and expose individual attributes with a JSONFlattener.
If you use the XMLFragmenter with Elements to Match set to "feature" and flattening enabled you will end up with a key-value pair list for each feature
ex.
'attribuut{0}' has value `muur'
'attribuut{0}.naam' has value `type'
'attribuut{1}' has value `bestaad'
'attribuut{1}.naam' has value `IMGEO status'
You can then loop through the list and turn each element pair into an attribute.
ex with an attribute creator
@Value(attribuut{0}.naam) ; attribuut{0}
If on the other hand you want one feature per attribute you can set the fragmenter to attribuut and you will end up with attribuut = muur, attribuut.naam = type, and you can do the same thing without the list indexes.
@jdh thank you for your solution. the only problem i have is to make the attribuut{}.naam the attribute name and the attribuut{} value the value of attribuut.naam{}.
Every object has its own attributes so i have to split every object and define its attributes.
I also think @jdh's solution is good enough, but, sorry, I cannot resist to try an XQuery solution...
Assuming the feature has an attribute called "xml_fragment" that stores an XML fragment. e.g.
<SHD>
<feature datadefinitie="Sleutels" code="SLEUTELS">
<attribuut naam="gisobjectnummeer">105963</attribuut>
</feature>
<feature datadefinitie="IMG" code="SHDV">
<attribuut naam="type">muur</attribuut>
<attribuut naam="IMGEO status">bestaand</attribuut>
<attribuut naam="In onderzoek">Nee</attribuut>
<attribuut naam="relatieveHoogteligging">0</attribuut>
<attribuut naam="identificatie">P0027.cdffbb11ae7c4f56a96af8f6c17cefb5</attribuut>
<attribuut naam="tijadstipRegistratie">20170626172844000</attribuut>
</feature>
<feature datadefinitie="GBK_LKI" code="C"></feature>
</SHD>
A JSONTemplater with this expression creates the following JSON object.JSONTemplater | Template Expression (XQuery expression)
let $x := fme:get-xml-attribute("xml_fragment")
let $members := {
for $a in $x//attribuut
return '"'||string($a/@naam)||'":"'||$a/text()||'"'
}
return '{'||fn:string-join($members, ',')||'}'
Resulting JSON Object:
{
"gisobjectnummeer" : "105963",
"type" : "muur",
"IMGEO status" : "bestaand",
"In onderzoek" : "Nee",
"relatieveHoogteligging" : "0",
"identificatie" : "P0027.cdffbb11ae7c4f56a96af8f6c17cefb5",
"tijadstipRegistratie" : "20170626172844000"
}
You can then extract and expose individual attributes with a JSONFlattener.
@takashi Thank you for your solution. the json is new for me and i think i give it a try.
@jdh thank you for your solution. the only problem i have is to make the attribuut{}.naam the attribute name and the attribuut{} value the value of attribuut.naam{}.
Every object has its own attributes so i have to split every object and define its attributes.
And that's where the @Value(attribuut{0}.naam) ; attribuut{0} part comes in - if you put that in an AttributeCreator it will create the attributes you need.
That technique is what I first thought of too - but perhaps there is a better way. I will look into it.
And that's where the @Value(attribuut{0}.naam) ; attribuut{0} part comes in - if you put that in an AttributeCreator it will create the attributes you need.
That technique is what I first thought of too - but perhaps there is a better way. I will look into it.
I actually still use the fme function caller with @SupplyAttributes, but that's a bit esoteric. If I don't need to access the attributes later in the workspace (just write them out dynamically) I would use python.
Ah! I see there is already a custom transformer on the FME Hub that will do what you need.
So... do as @jdh suggests and use the XMLFragmenter to create your list of attributes.
Then use a ListKeyValuePairExtractor transformer (you might need FME2017.1) and it will convert your list into true attributes. Simple.
Ah! I see there is already a custom transformer on the FME Hub that will do what you need.
So... do as @jdh suggests and use the XMLFragmenter to create your list of attributes.
Then use a ListKeyValuePairExtractor transformer (you might need FME2017.1) and it will convert your list into true attributes. Simple.
Nice work @sander_s for the hub transformer. Very useful.
I also think @jdh's solution is good enough, but, sorry, I cannot resist to try an XQuery solution...
Assuming the feature has an attribute called "xml_fragment" that stores an XML fragment. e.g.
<SHD>
<feature datadefinitie="Sleutels" code="SLEUTELS">
<attribuut naam="gisobjectnummeer">105963</attribuut>
</feature>
<feature datadefinitie="IMG" code="SHDV">
<attribuut naam="type">muur</attribuut>
<attribuut naam="IMGEO status">bestaand</attribuut>
<attribuut naam="In onderzoek">Nee</attribuut>
<attribuut naam="relatieveHoogteligging">0</attribuut>
<attribuut naam="identificatie">P0027.cdffbb11ae7c4f56a96af8f6c17cefb5</attribuut>
<attribuut naam="tijadstipRegistratie">20170626172844000</attribuut>
</feature>
<feature datadefinitie="GBK_LKI" code="C"></feature>
</SHD>
A JSONTemplater with this expression creates the following JSON object.JSONTemplater | Template Expression (XQuery expression)
let $x := fme:get-xml-attribute("xml_fragment")
let $members := {
for $a in $x//attribuut
return '"'||string($a/@naam)||'":"'||$a/text()||'"'
}
return '{'||fn:string-join($members, ',')||'}'
Resulting JSON Object:
{
"gisobjectnummeer" : "105963",
"type" : "muur",
"IMGEO status" : "bestaand",
"In onderzoek" : "Nee",
"relatieveHoogteligging" : "0",
"identificatie" : "P0027.cdffbb11ae7c4f56a96af8f6c17cefb5",
"tijadstipRegistratie" : "20170626172844000"
}
You can then extract and expose individual attributes with a JSONFlattener.
wow, I found that the XMLXQueryUpdater can be used to extract individual attributes directly from the XML fragment with this small expression.
for $a in //attribuut
return fme:set-attribute($a/@naam, $a/text())
Interesting. It would be more useful if the Attributes to Expose parameters would be added to the transformer.
I also think @jdh's solution is good enough, but, sorry, I cannot resist to try an XQuery solution...
Assuming the feature has an attribute called "xml_fragment" that stores an XML fragment. e.g.
<SHD>
<feature datadefinitie="Sleutels" code="SLEUTELS">
<attribuut naam="gisobjectnummeer">105963</attribuut>
</feature>
<feature datadefinitie="IMG" code="SHDV">
<attribuut naam="type">muur</attribuut>
<attribuut naam="IMGEO status">bestaand</attribuut>
<attribuut naam="In onderzoek">Nee</attribuut>
<attribuut naam="relatieveHoogteligging">0</attribuut>
<attribuut naam="identificatie">P0027.cdffbb11ae7c4f56a96af8f6c17cefb5</attribuut>
<attribuut naam="tijadstipRegistratie">20170626172844000</attribuut>
</feature>
<feature datadefinitie="GBK_LKI" code="C"></feature>
</SHD>
A JSONTemplater with this expression creates the following JSON object.JSONTemplater | Template Expression (XQuery expression)
let $x := fme:get-xml-attribute("xml_fragment")
let $members := {
for $a in $x//attribuut
return '"'||string($a/@naam)||'":"'||$a/text()||'"'
}
return '{'||fn:string-join($members, ',')||'}'
Resulting JSON Object:
{
"gisobjectnummeer" : "105963",
"type" : "muur",
"IMGEO status" : "bestaand",
"In onderzoek" : "Nee",
"relatieveHoogteligging" : "0",
"identificatie" : "P0027.cdffbb11ae7c4f56a96af8f6c17cefb5",
"tijadstipRegistratie" : "20170626172844000"
}
You can then extract and expose individual attributes with a JSONFlattener.
The XMLXQueryExtractor does the same thing, and also it has the "Attributes to Expose" parameter, so it might be better in this case.
I also think @jdh's solution is good enough, but, sorry, I cannot resist to try an XQuery solution...
Assuming the feature has an attribute called "xml_fragment" that stores an XML fragment. e.g.
<SHD>
<feature datadefinitie="Sleutels" code="SLEUTELS">
<attribuut naam="gisobjectnummeer">105963</attribuut>
</feature>
<feature datadefinitie="IMG" code="SHDV">
<attribuut naam="type">muur</attribuut>
<attribuut naam="IMGEO status">bestaand</attribuut>
<attribuut naam="In onderzoek">Nee</attribuut>
<attribuut naam="relatieveHoogteligging">0</attribuut>
<attribuut naam="identificatie">P0027.cdffbb11ae7c4f56a96af8f6c17cefb5</attribuut>
<attribuut naam="tijadstipRegistratie">20170626172844000</attribuut>
</feature>
<feature datadefinitie="GBK_LKI" code="C"></feature>
</SHD>
A JSONTemplater with this expression creates the following JSON object.JSONTemplater | Template Expression (XQuery expression)
let $x := fme:get-xml-attribute("xml_fragment")
let $members := {
for $a in $x//attribuut
return '"'||string($a/@naam)||'":"'||$a/text()||'"'
}
return '{'||fn:string-join($members, ',')||'}'
Resulting JSON Object:
{
"gisobjectnummeer" : "105963",
"type" : "muur",
"IMGEO status" : "bestaand",
"In onderzoek" : "Nee",
"relatieveHoogteligging" : "0",
"identificatie" : "P0027.cdffbb11ae7c4f56a96af8f6c17cefb5",
"tijadstipRegistratie" : "20170626172844000"
}
You can then extract and expose individual attributes with a JSONFlattener.
The xmlXQueryExtractor does the job. exactly what i was looking for. Thank you @takashi
If you use the XMLFragmenter with Elements to Match set to "feature" and flattening enabled you will end up with a key-value pair list for each feature
ex.
'attribuut{0}' has value `muur'
'attribuut{0}.naam' has value `type'
'attribuut{1}' has value `bestaad'
'attribuut{1}.naam' has value `IMGEO status'
You can then loop through the list and turn each element pair into an attribute.
ex with an attribute creator
@Value(attribuut{0}.naam) ; attribuut{0}
If on the other hand you want one feature per attribute you can set the fragmenter to attribuut and you will end up with attribuut = muur, attribuut.naam = type, and you can do the same thing without the list indexes.
I have exposed 39 attribute pairs along with the default xml attributes using the XML-Fragmenter. They are in the form: Property || Value in the FME Data Inspector. None of the methods above allow me to extract these values.