Skip to main content

Hello,

as the title already implies, I'm trying to merge XML formatted text ("insert") into a similarly ISO19115-1 formatted root template ("template"- see attachments) in a XML Templater feature.

The insert (see attachment) is put together in a String concatenator feature from a set of values extracted from a database in a previous stage of the workflow and stored in an attribute named "SCIENTIST_INFORMATION". AFAIK I have two options to achieve what I want:

 

*Option 1 - plain 'fme:get-attribute()' *:

If I use a simple {fme:get-attribute("SCIENTIST_INFORMATION")} the templater replaces XML special chars with their respective protected counterpart (e.g. < with &lt;), rendering the text insert into something I do not intend. Note that I cannot reverse these transformation with a string replacer after the templater, as this also replaces non-XML specific special characters making the resulting XML files invalid.

 

*Option 2 - 'fme:get-xml-attribute(…)'*:

When I try to apply the insert via this feature, the Templater complains about invalid or missing namespace declarations. Introducing declarations to the insert (see second attachment) following a hint of @Takashi Iijima​  in one of the other issues, the templater no longer complains about namespaces, but gives a rather cryptic "parsing error: Extra content at the end of the document" (see attached log excerpt …error-log.txt for more details) omitting the insert entirely.

 

Any hint or idea would be highly appreciated. Thank you!

lmoeller

Hi @lmoeller​ , could you please post the value (XML formatted text?) of the attribute called "SCIENTIST_INFORMATION" and the template expression which you have set to the XMLTemplater?


Hi @Takashi Iijima​ ,

of course I can - I thought it might clutter up the thread too much.

Here is the XML insert:

        <mri:pointOfContact xmlns:mdb="http://standards.iso.org/iso/19115/-3/mdb/2.0"

                xmlns:cit="http://standards.iso.org/iso/19115/-3/cit/2.0"

                xmlns:mri="http://standards.iso.org/iso/19115/-3/mri/1.0"

                xmlns:gco="http://standards.iso.org/iso/19115/-3/gco/1.0">

           <cit:CI_Responsibility>

              <cit:role>

                 <cit:CI_RoleCode codeList="https://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#CI_RoleCode"

                                  codeListValue="originator">originator</cit:CI_RoleCode>

              </cit:role>

              <cit:party>

                …

              </cit:party>

           </cit:CI_Responsibility>

        </mri:pointOfContact>


And here the root for the templater:

 

<?xml version="1.0" encoding="UTF-8"?>

<mdb:MD_Metadata xmlns:mdb="http://standards.iso.org/iso/19115/-3/mdb/2.0"

                xmlns:cat="http://standards.iso.org/iso/19115/-3/cat/1.0"

                xmlns:gfc="http://standards.iso.org/iso/19110/gfc/1.1"

                xmlns:cit="http://standards.iso.org/iso/19115/-3/cit/2.0"

                xmlns:gcx="http://standards.iso.org/iso/19115/-3/gcx/1.0"

                xmlns:gex="http://standards.iso.org/iso/19115/-3/gex/1.0"

                xmlns:lan="http://standards.iso.org/iso/19115/-3/lan/1.0"

                xmlns:srv="http://standards.iso.org/iso/19115/-3/srv/2.1"

                xmlns:mas="http://standards.iso.org/iso/19115/-3/mas/1.0"

                xmlns:mcc="http://standards.iso.org/iso/19115/-3/mcc/1.0"

                xmlns:mco="http://standards.iso.org/iso/19115/-3/mco/1.0"

                xmlns:mda="http://standards.iso.org/iso/19115/-3/mda/1.0"

                xmlns:mds="http://standards.iso.org/iso/19115/-3/mds/2.0"

                xmlns:mdt="http://standards.iso.org/iso/19115/-3/mdt/2.0"

                xmlns:mex="http://standards.iso.org/iso/19115/-3/mex/1.0"

                xmlns:mmi="http://standards.iso.org/iso/19115/-3/mmi/1.0"

                xmlns:mpc="http://standards.iso.org/iso/19115/-3/mpc/1.0"

                xmlns:mrc="http://standards.iso.org/iso/19115/-3/mrc/2.0"

                xmlns:mrd="http://standards.iso.org/iso/19115/-3/mrd/1.0"

                xmlns:mri="http://standards.iso.org/iso/19115/-3/mri/1.0"

                xmlns:mrl="http://standards.iso.org/iso/19115/-3/mrl/2.0"

                xmlns:mrs="http://standards.iso.org/iso/19115/-3/mrs/1.0"

                xmlns:msr="http://standards.iso.org/iso/19115/-3/msr/2.0"

                xmlns:mdq="http://standards.iso.org/iso/19157/-2/mdq/1.0"

                xmlns:mac="http://standards.iso.org/iso/19115/-3/mac/2.0"

                xmlns:gco="http://standards.iso.org/iso/19115/-3/gco/1.0"

                xmlns:gml="http://www.opengis.net/gml/3.2"

                xmlns:xlink="http://www.w3.org/1999/xlink"

                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                xsi:schemaLocation="http://standards.iso.org/iso/19115/-3/mds/2.0 http://standards.iso.org/iso/19115/-3/mds/2.0/mds.xsd">

 <mdb:metadataIdentifier>

     <mcc:MD_Identifier>

        <mcc:code>

           <gco:CharacterString>{fme:get-attribute("UUID")}</gco:CharacterString>

        </mcc:code>

        <mcc:codeSpace>

           <gco:CharacterString>UUID</gco:CharacterString>

        </mcc:codeSpace>

     </mcc:MD_Identifier>

 </mdb:metadataIdentifier>

 <mdb:defaultLocale>

     <lan:PT_Locale>

        <lan:language>

           <lan:LanguageCode codeList="https://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#LanguageCode"

                             codeListValue="eng">eng</lan:LanguageCode>

        </lan:language>

        <lan:characterEncoding>

           <lan:MD_CharacterSetCode codeList="https://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#MD_CharacterSetCode"

                                    codeListValue="utf8">utf8</lan:MD_CharacterSetCode>

        </lan:characterEncoding>

     </lan:PT_Locale>

 </mdb:defaultLocale>

 <mdb:metadataScope>

     <mdb:MD_MetadataScope>

        <mdb:resourceScope>

           <mcc:MD_ScopeCode codeList="https://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#MD_ScopeCode"

                             codeListValue="dataset">dataset</mcc:MD_ScopeCode>

        </mdb:resourceScope>

     </mdb:MD_MetadataScope>

 </mdb:metadataScope>

 <mdb:identificationInfo>

     <mri:MD_DataIdentification>

{fme:get-xml-attribute("SCIENTIST_INFO_LIST-ISO2014")}

</mdb:MD_Metadata>

 


@Takashi Iijima​ Anything else I could provide to further this?


@Takashi Iijima​ Anything else I could provide to further this?

As far as I see the XML and the template expression you have posted, I can't find anything wrong. According to the error message, however, it seems that the issue occurred while executing the fme:get-xml-attribute function. Possibly the error could be hidden in the part you have omitted in the posted documents.


As far as I see the XML and the template expression you have posted, I can't find anything wrong. According to the error message, however, it seems that the issue occurred while executing the fme:get-xml-attribute function. Possibly the error could be hidden in the part you have omitted in the posted documents.

Hi @Takashi Iijima​ ,

sorry for not coming back to this earlier. I had a few weeks off for vacation and other projects. But I'd still love to solve this little showstopper. And, if I am lucky, with the help of your support.

It is strange, I checked for other fme:get-xml-attribute calls in the root template and couldn't find any. And the respective insert is the only one omitted in the templater output afaics.

However, for your reference, I attached the full document (needed depersonalization still).

Hopefully you have an idea, I surely don't.

 

My best regards and warmest thanks!

lmoeller


I wasn't able to reproduce the error with the template expression you have posted, but the same error occured once I added an extra character (e.g. a comma) at the end of the value of "SCIENTIST_INFO_LIST-ISO2014" (the xml document to be inserted with the fme:get-xml-attribute function).

XMLTemplater (XMLTemplaterFactory): The following error occurred while executing the fme:get-xml-attribute function:
XMLTemplater (XMLTemplaterFactory): The following error occurred near line 1, column 51 of the query:
XMLTemplater (XMLTemplaterFactory): invalid content passed to fn:parse-xml(): loader parsing error: Extra content at the end of the document

Please validate again the XML document stored in the "SCIENTIST_INFO_LIST-ISO2014".


What I have done in the past is do the merge outside of the XMLTemplater. So just have a placeholder string in the XMLTemplater and then use a StringReplacer to swap that out with the XML you want added in.


I wasn't able to reproduce the error with the template expression you have posted, but the same error occured once I added an extra character (e.g. a comma) at the end of the value of "SCIENTIST_INFO_LIST-ISO2014" (the xml document to be inserted with the fme:get-xml-attribute function).

XMLTemplater (XMLTemplaterFactory): The following error occurred while executing the fme:get-xml-attribute function:
XMLTemplater (XMLTemplaterFactory): The following error occurred near line 1, column 51 of the query:
XMLTemplater (XMLTemplaterFactory): invalid content passed to fn:parse-xml(): loader parsing error: Extra content at the end of the document

Please validate again the XML document stored in the "SCIENTIST_INFO_LIST-ISO2014".

Ahh, we have a new lead! There are a few datasets were the incoming "SCIENTIST_INFO_LIST-ISO2014" only contains information of one person -  in these cases the templater function actually works. 

However, in most of the cases the"SCIENTIST_INFO_LIST-ISO2014" contains two or more scientists. And then "SCIENTIST_INFO_LIST-ISO2014" insert might look like this:

         <mri:pointOfContact xmlns:mdb="http://standards.iso.org/iso/19115/-3/mdb/2.0"
                 xmlns:cit="http://standards.iso.org/iso/19115/-3/cit/2.0"
                 xmlns:mri="http://standards.iso.org/iso/19115/-3/mri/1.0"
                 xmlns:gco="http://standards.iso.org/iso/19115/-3/gco/1.0">
            <cit:CI_Responsibility>

            </cit:CI_Responsibility>
         </mri:pointOfContact>         <mri:pointOfContact xmlns:mdb="http://standards.iso.org/iso/19115/-3/mdb/2.0"
                 xmlns:cit="http://standards.iso.org/iso/19115/-3/cit/2.0"
                 xmlns:mri="http://standards.iso.org/iso/19115/-3/mri/1.0"
                 xmlns:gco="http://standards.iso.org/iso/19115/-3/gco/1.0">
            <cit:CI_Responsibility>

            </cit:CI_Responsibility>
         </mri:pointOfContact>

I suppose the missing root element and/or double namespace declarations in these cases makes the templater fail.

Will I  have to split the insert into multiple parts and add them with the appropriate amount of templaters or could I manage it in a loop construction (like fn:tokenize)). But what could be the delimiter in the case? Would you think that "</mri:pointOfContact>        <mri:pointOfContact" might work?

Thanks again, @takashi


What I have done in the past is do the merge outside of the XMLTemplater. So just have a placeholder string in the XMLTemplater and then use a StringReplacer to swap that out with the XML you want added in.

Why didn't I think of that? Simple and effective - and works! Thanks for sharing!


I wasn't able to reproduce the error with the template expression you have posted, but the same error occured once I added an extra character (e.g. a comma) at the end of the value of "SCIENTIST_INFO_LIST-ISO2014" (the xml document to be inserted with the fme:get-xml-attribute function).

XMLTemplater (XMLTemplaterFactory): The following error occurred while executing the fme:get-xml-attribute function:
XMLTemplater (XMLTemplaterFactory): The following error occurred near line 1, column 51 of the query:
XMLTemplater (XMLTemplaterFactory): invalid content passed to fn:parse-xml(): loader parsing error: Extra content at the end of the document

Please validate again the XML document stored in the "SCIENTIST_INFO_LIST-ISO2014".

The "SCIENTIST_INFO_LIST-ISO2014" should be a single XML fragment. Missing a common parent (root) element of the multiple mri:pointOfContact elements was reason for the error.

A simple workaround is: create a single XML element that contains the multiple mri:pointOfContact elements and store it as a new attribute (e.g. named "_scientist_infos") with the AttributeCreator or the StringConcatenator,

<infos>
@Value(SCIENTIST_INFO_LIST-ISO2014)
</infos>

then embed this expression into the template expression to insert the child elements (i.e. multiple mri:pointOfContact).

{
    for $x in fme:get-xml-attribute("_scientist_infos")/infos/mri:pointOfContact
    return $x
}

 


The "SCIENTIST_INFO_LIST-ISO2014" should be a single XML fragment. Missing a common parent (root) element of the multiple mri:pointOfContact elements was reason for the error.

A simple workaround is: create a single XML element that contains the multiple mri:pointOfContact elements and store it as a new attribute (e.g. named "_scientist_infos") with the AttributeCreator or the StringConcatenator,

<infos>
@Value(SCIENTIST_INFO_LIST-ISO2014)
</infos>

then embed this expression into the template expression to insert the child elements (i.e. multiple mri:pointOfContact).

{
    for $x in fme:get-xml-attribute("_scientist_infos")/infos/mri:pointOfContact
    return $x
}

 

Awesome @Takashi Iijima​ - that did the trick!

And again, I could even learn a thing or two, so I think its even a better solution than the one of @Gary Nicholson​ 

Nevertheless, thanks to both of you once again!


Reply