Hi @philippe33, the XMLFragmenter might help you. Assuming that the name of the parent element of the annotation elements is "parent", fragment the XML document with these parameters.
- Elements to Match: parent
- Elements as XML Fragments: annotation
- Attributes to Expose: xml_fragment_annotation{}
The XMLFragmenter outputs a feature containing a list called "xml_fragment_annotation{}" which stores every annotation XML fragment as its elements.
You can then rename the list to "annotation{}" with the ListRenamer or the AttributeManager.
Hope this helps.
Hi @takashi
I give some precisions about my request. i don't speak english a lot
My problem : With XML templater i test if some attributes exist or not. If they exist, i write a small part of XML for each attributes which are found. A little xml fragment if i find attribute "X", a little xml fragment for the attribute "Y" .... i make 3 tests
templater.png
the XML part is like this :
templater-xml.png
I obtain a lot of result with the templater. For one feature i can obtain 3 elements XML maximum
Â
xmltemplater-output.png
Â
At the end, in the final schema i have to write in a list, not in a xml fragment
ecriture.png
with the xml_fragmenter it make me the job only one time per feature in input. if it had many "annotation" in the xml fragment it gives me an error
erreur.png
some advice ?
With the limited information, it's hard to understand correctly what you intend to do.
If you are going to create 932 <annotation> fragments for each input feature, and the contents could be different depending on attribute value(s) of the input feature, this mock-up ROOT template might be helpful. Assuming that the input feature has an attribute called "n" and it can store 0, 1, or other.
<annotation>{
let $n := fme:get-attribute("n")
return
    if ($n eq 0) then {
        <foo />
    }
    else if ($n eq 1) then {
        <bar />
    }
    else {
        <foobar />
    }
}</annotation>
Naturally the contents corresponding to each condition can also be supplied by SUB templates, but you will have to set the "Group Sub-Features By" parameter to group a ROOT feature and corresponding SUB features. The ROOT template looks like this. Assuming that X, Y, and Z are the sub template port names.Â
<annotation>{
let $n := fme:get-attribute("n")
return
    if ($n eq 0) then {
        fme:process-features("X")
    }
    else if ($n eq 1) then {
        fme:process-features("Y")
    }
    else {
        fme:process-features("Z")
    }
}</annotation>
Your template expression generates a sequence of 0 - 3 annotation elements, but they cannot be handled as an XML fragment in the subsequent workflow, since they don't belong to a common parent.
If you use the XMLFragmenter to populate the annotation elements to a list, you have to fix the expression to generate a single XML element that contains the annotation elements as children. e.g.
(: replace ocondition] with the actual condition expression :)
(: Update: Changed every "fme:process-features" to "fme:process-template" :)
<parent>{
    {
        if (ocondition]) then {fme:process-template("X")}
        else ()
    },
    {
        if (hcondition]) then {fme:process-template("Y")}
        else ()
    },
    {
        if (Âcondition]) then {fme:process-template("Z")}
        else ()
    }
}</parent>
Alternatively, the StringSearcher could be used to populate the annotation elements to a list. Set this regular expression and specify "All Matches List Name".
<aixm:annotation.+?</aixm:annotation>
Anyway, I think you will have to use the "Group Sub-Features By" parameter in the XMLTemplater_6 to group a ROOT and a set of X, Y, and Z.
+Update] I didn't notice that you are using the "fme:process-template" function in the template expression, rather than the "fme:process-features" function.
If you use the "fme:process-template" function, it may not be essential to set the "Group Sub-Features By" parameter.Â
It seems that the only difference among X, Y, and Z expressions is the contents of the <aixm:note> element. If I have understood your intention correctly, the four expressions (ROOT, X, Y, and Z) could be integrated/simplified into a single ROOT expression like this.
declare namespace aixm="http://www.aixm.aero/schema/5.1";
declare namespace gml="http://www.opengis.net/gml/3.2";
<parent>{
    let $id := fme:get-attribute("gml_id")
    let $texts := (
        {
            let $t := fme:get-attribute("txtDescrSite")
            return if ($t ne "") then "Site description: "||$t else ""
        },
        {
            let $t := fme:get-attribute("txtNameAdmin")
            return if ($t ne "") then "Organisation in charge: "||$t else ""
        },
        {
            let $t := fme:get-attribute("txtDescrRefPt")
            return if ($t ne "") then $t else ""
        }
    )
    for $txt in $texts where $txt ne ""
    return
    <aixm:annotation>
        <aixm:Note gml:id="{"n"||$id||"_0"}">
            <aixm:purpose>DESCRIPTION</aixm:purpose>
            <aixm:translatedNote>
                <aixm:LinguisticNote gml:id="{"ln"||$id||"_0"}">
                    <aixm:note>{$txt}</aixm:note>
                </aixm:LinguisticNote>
            </aixm:translatedNote>
        </aixm:Note>
    </aixm:annotation>
}</parent>
If you don't need to surround the sequence of <aixm:annotation> elements by the <parent> element, remove these two lines from the expression above.
<parent>{
}</parent>