Skip to main content
Solved

Creating seperate attribute input for get-list-attribute in XML?


Forum|alt.badge.img

Hello everybody, i have an xml file metadata, and i am converting it into another metadata standard. i have mapped both but problem is created by list values. I have attached two screeshorts,

the following screenshort will show the result. Attribute Name and datatype is getting value in list, but i want them as individual entry. How can I get it in final xml file?

Thanks

Best answer by takashi

Perhaps are you using FME 2016? Since FME 2016 treats the value of "_element_count" as a string, you will have to explicitly convert it to integer in the expression like this.

let $n := xs:integer(fme:get-attribute("_element_count")) - 1

My previous example was to repeat <CharacterString> element within a single parent element, but looks like it would not  match your desired result. If you need to repeat <column> element which contains <name> and <type> elements as its descendants, this example might be better for you. Assuming that the input feature has a list attribute called "attr{}.name", "attr{}.type".

<parent>{
let $n := xs:integer(fme:get-attribute("_element_count")) - 1
for $i in (0 to $n)
let $aname := "attr{"||$i||"}.name"
let $atype := "attr{"||$i||"}.type"
return
    <column>
        <name>
            <CharacterString>{fme:get-attribute($aname)}</CharacterString>
        </name>
        <type>
            <CharacterString>{fme:get-attribute($atype)}</CharacterString>
        </type>
    </column>
}</parent>

input:

attr{}.name contains "foo""bar"and "foobar"
attr{}.type contains "string""integer"and "double"

result:

<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <column>
        <name>
            <CharacterString>foo</CharacterString>
        </name>
        <type>
            <CharacterString>string</CharacterString>
        </type>
    </column>
    <column>
        <name>
            <CharacterString>bar</CharacterString>
        </name>
        <type>
            <CharacterString>integer</CharacterString>
        </type>
    </column>
    <column>
        <name>
            <CharacterString>foobar</CharacterString>
        </name>
        <type>
            <CharacterString>double</CharacterString>
        </type>
    </column>
</parent>
View original
Did this help you find an answer to your question?

6 replies

takashi
Influencer
  • July 31, 2017

Hi @mjoarder_pln, this is a simplified example.

Assuming that a list attribute called "attr{}.type" contains these values,

attr{0}.type = string
attr{1}.type = integer
attr{2}.type = double

and the number of elements ("_element_count" attribute) has been extracted by the ListElementCounter beforehand, this XML template (XQuery) expression creates the following XML fragment.

(: XMLTemplater Template Expression Example :)
<dataType>{
let $n := fme:get-attribute("_element_count") - 1
for $i in (0 to $n)
let $attr := "attr{"||$i||"}.type"
return
    <CharacterString>{fme:get-attribute($attr)}</CharacterString>
}</dataType>
<?xml version="1.0" encoding="UTF-8"?>
<dataType>
    <CharacterString>string</CharacterString>
    <CharacterString>integer</CharacterString>
    <CharacterString>double</CharacterString>
</dataType>

Forum|alt.badge.img
takashi wrote:

Hi @mjoarder_pln, this is a simplified example.

Assuming that a list attribute called "attr{}.type" contains these values,

attr{0}.type = string
attr{1}.type = integer
attr{2}.type = double

and the number of elements ("_element_count" attribute) has been extracted by the ListElementCounter beforehand, this XML template (XQuery) expression creates the following XML fragment.

(: XMLTemplater Template Expression Example :)
<dataType>{
let $n := fme:get-attribute("_element_count") - 1
for $i in (0 to $n)
let $attr := "attr{"||$i||"}.type"
return
    <CharacterString>{fme:get-attribute($attr)}</CharacterString>
}</dataType>
<?xml version="1.0" encoding="UTF-8"?>
<dataType>
    <CharacterString>string</CharacterString>
    <CharacterString>integer</CharacterString>
    <CharacterString>double</CharacterString>
</dataType>

 

Hi, i have applied your code example in my ROOT Template example, but it is not working, please see the following two screenshort. xml_1 and xml_2. 

 

 

0684Q00000ArME9QAN.png

No data is inserting inside xml...

 

 

0684Q00000ArMGjQAN.png

 

I want to see the values like this:

 

 

0684Q00000ArMIPQA3.png

All the different column names and data types will come inside their own parent elements.

 

 

 

Thanks

 


Forum|alt.badge.img
takashi wrote:

Hi @mjoarder_pln, this is a simplified example.

Assuming that a list attribute called "attr{}.type" contains these values,

attr{0}.type = string
attr{1}.type = integer
attr{2}.type = double

and the number of elements ("_element_count" attribute) has been extracted by the ListElementCounter beforehand, this XML template (XQuery) expression creates the following XML fragment.

(: XMLTemplater Template Expression Example :)
<dataType>{
let $n := fme:get-attribute("_element_count") - 1
for $i in (0 to $n)
let $attr := "attr{"||$i||"}.type"
return
    <CharacterString>{fme:get-attribute($attr)}</CharacterString>
}</dataType>
<?xml version="1.0" encoding="UTF-8"?>
<dataType>
    <CharacterString>string</CharacterString>
    <CharacterString>integer</CharacterString>
    <CharacterString>double</CharacterString>
</dataType>
<bnr:MD_DataSchema>

 

  <bnr:column>

 

  <bnr:MD_Column>

 

  <bnr:name>

 

  {

 

  let $n := fme:get-attribute("_element_count") - 1

 

for $i in (0 to $n)

 

let $attr := "eainfo.detailed.attr{"||$i||"}.attrlabl"

 

return

 

  <gco:CharacterString>{fme:get-attribute($attr)}</gco:CharacterString>

 

  }</bnr:name>

 

  <bnr:description>

 

  <gco:CharacterString/>

 

  </bnr:description>

 

  <bnr:dataType>{

 

  let $n := fme:get-attribute("_element_count") - 1

 

for $i in (0 to $n)

 

let $attr1 := "eainfo.detailed.attr{"||$i||"}.attrtype"

 

return 

 

  <gco:CharacterString>{fme:get-attribute($attr1)}</gco:CharacterString>

 

  }</bnr:dataType>

 

#

 

 

 

 

 

giving me the following error:

 

XMLTemplater(XMLTemplaterFactory): The following error occurred near line 62, column 17 of the query:
XMLTemplater(XMLTemplaterFactory): arithmetic operation not defined between types "xs:string" and "xs:integer"

 


A fatal error has occurred. Check the logfile above for details

 


|ERROR |

 

 

 

 


takashi
Influencer
  • Best Answer
  • August 1, 2017

Perhaps are you using FME 2016? Since FME 2016 treats the value of "_element_count" as a string, you will have to explicitly convert it to integer in the expression like this.

let $n := xs:integer(fme:get-attribute("_element_count")) - 1

My previous example was to repeat <CharacterString> element within a single parent element, but looks like it would not  match your desired result. If you need to repeat <column> element which contains <name> and <type> elements as its descendants, this example might be better for you. Assuming that the input feature has a list attribute called "attr{}.name", "attr{}.type".

<parent>{
let $n := xs:integer(fme:get-attribute("_element_count")) - 1
for $i in (0 to $n)
let $aname := "attr{"||$i||"}.name"
let $atype := "attr{"||$i||"}.type"
return
    <column>
        <name>
            <CharacterString>{fme:get-attribute($aname)}</CharacterString>
        </name>
        <type>
            <CharacterString>{fme:get-attribute($atype)}</CharacterString>
        </type>
    </column>
}</parent>

input:

attr{}.name contains "foo""bar"and "foobar"
attr{}.type contains "string""integer"and "double"

result:

<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <column>
        <name>
            <CharacterString>foo</CharacterString>
        </name>
        <type>
            <CharacterString>string</CharacterString>
        </type>
    </column>
    <column>
        <name>
            <CharacterString>bar</CharacterString>
        </name>
        <type>
            <CharacterString>integer</CharacterString>
        </type>
    </column>
    <column>
        <name>
            <CharacterString>foobar</CharacterString>
        </name>
        <type>
            <CharacterString>double</CharacterString>
        </type>
    </column>
</parent>

takashi
Influencer
  • August 1, 2017
takashi wrote:

Perhaps are you using FME 2016? Since FME 2016 treats the value of "_element_count" as a string, you will have to explicitly convert it to integer in the expression like this.

let $n := xs:integer(fme:get-attribute("_element_count")) - 1

My previous example was to repeat <CharacterString> element within a single parent element, but looks like it would not  match your desired result. If you need to repeat <column> element which contains <name> and <type> elements as its descendants, this example might be better for you. Assuming that the input feature has a list attribute called "attr{}.name", "attr{}.type".

<parent>{
let $n := xs:integer(fme:get-attribute("_element_count")) - 1
for $i in (0 to $n)
let $aname := "attr{"||$i||"}.name"
let $atype := "attr{"||$i||"}.type"
return
    <column>
        <name>
            <CharacterString>{fme:get-attribute($aname)}</CharacterString>
        </name>
        <type>
            <CharacterString>{fme:get-attribute($atype)}</CharacterString>
        </type>
    </column>
}</parent>

input:

attr{}.name contains "foo""bar"and "foobar"
attr{}.type contains "string""integer"and "double"

result:

<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <column>
        <name>
            <CharacterString>foo</CharacterString>
        </name>
        <type>
            <CharacterString>string</CharacterString>
        </type>
    </column>
    <column>
        <name>
            <CharacterString>bar</CharacterString>
        </name>
        <type>
            <CharacterString>integer</CharacterString>
        </type>
    </column>
    <column>
        <name>
            <CharacterString>foobar</CharacterString>
        </name>
        <type>
            <CharacterString>double</CharacterString>
        </type>
    </column>
</parent>
This expression generates the same result.

 

<parent>{
let $names := fme:get-list-attribute("attr{}.name")
let $types := fme:get-list-attribute("attr{}.type")
for $i in (1 to fn:count($names))
return
    <column>
        <name>
            <CharacterString>{$names[$i]}</CharacterString>
        </name>
        <type>
            <CharacterString>{$types[$i]}</CharacterString>
        </type>
    </column>
}</parent>

 


Forum|alt.badge.img
takashi wrote:

Perhaps are you using FME 2016? Since FME 2016 treats the value of "_element_count" as a string, you will have to explicitly convert it to integer in the expression like this.

let $n := xs:integer(fme:get-attribute("_element_count")) - 1

My previous example was to repeat <CharacterString> element within a single parent element, but looks like it would not  match your desired result. If you need to repeat <column> element which contains <name> and <type> elements as its descendants, this example might be better for you. Assuming that the input feature has a list attribute called "attr{}.name", "attr{}.type".

<parent>{
let $n := xs:integer(fme:get-attribute("_element_count")) - 1
for $i in (0 to $n)
let $aname := "attr{"||$i||"}.name"
let $atype := "attr{"||$i||"}.type"
return
    <column>
        <name>
            <CharacterString>{fme:get-attribute($aname)}</CharacterString>
        </name>
        <type>
            <CharacterString>{fme:get-attribute($atype)}</CharacterString>
        </type>
    </column>
}</parent>

input:

attr{}.name contains "foo""bar"and "foobar"
attr{}.type contains "string""integer"and "double"

result:

<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <column>
        <name>
            <CharacterString>foo</CharacterString>
        </name>
        <type>
            <CharacterString>string</CharacterString>
        </type>
    </column>
    <column>
        <name>
            <CharacterString>bar</CharacterString>
        </name>
        <type>
            <CharacterString>integer</CharacterString>
        </type>
    </column>
    <column>
        <name>
            <CharacterString>foobar</CharacterString>
        </name>
        <type>
            <CharacterString>double</CharacterString>
        </type>
    </column>
</parent>
Hi, takashi , it works! Thanks a lot ...

 

 

 

 


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings