Home > database >  add 2 or more subnodes with xmlstarlet
add 2 or more subnodes with xmlstarlet

Time:09-28

I would like to achive this result using xmlstarlet

<mrd:transferOptions>
            <mrd:MD_DigitalTransferOptions>
               <mrd:onLine>
                  <cit:CI_OnlineResource>
                     <cit:linkage>
                        <gco:CharacterString>text</gco:CharacterString>
                     </cit:linkage>
                     <cit:protocol>
                        <gco:CharacterString>WWW:LINK-1.0-http--link</gco:CharacterString>
                     </cit:protocol>
                     <cit:name>
                        <gco:CharacterString>text 1</gco:CharacterString>
                     </cit:name>
                     <cit:description>
                        <gco:CharacterString>Text 2</gco:CharacterString>
                     </cit:description>
                     <cit:function>
                        <cit:CI_OnLineFunctionCode codeList="http://standards.iso.org/iso/19115/resources/Codelists/cat/codelists.xml#CI_OnLineFunctionCode"
                                                   codeListValue="doi"/>
                     </cit:function>
                  </cit:CI_OnlineResource>
               </mrd:onLine>
            </mrd:MD_DigitalTransferOptions>
</mrd:transferOptions>

to be added to my XSL file I'm using the following code:

xmlstarlet ed -N mdb="http://standards.iso.org/iso/19115/-3/mdb/2.0" -N mrd="http://standards.iso.org/iso/19115/-3/mrd/1.0" -N cit="http://standards.iso.org/iso/19115/-3/cit/2.0" -N gco="http://standards.iso.org/iso/19115/-3/gco/1.0" \
--subnode "//mdb:distributionInfo/mrd:MD_Distribution" -t elem -n 'mrd:transferOptions' -v "" \
--subnode '$prev' -t elem -n 'mrd:MD_DigitalTransferOptions' -v "" \
--subnode '$prev' -t elem -n 'mrd:onLine' -v "" \
--subnode '$prev' -t elem -n 'cit:CI_OnlineResource' -v "" \
--subnode '$prev' -t elem -n 'cit:linkage' -v "" \
--subnode '$prev' -t elem -n 'gco:CharacterString' -v "text" \
filx.xsl

to create the first part of my xml up to the element cit:linkage

How can I add the remaining elements?

I tried something like this to add the element cit:protocol

xmlstarlet ed -N mdb="http://standards.iso.org/iso/19115/-3/mdb/2.0" -N mrd="http://standards.iso.org/iso/19115/-3/mrd/1.0" -N cit="http://standards.iso.org/iso/19115/-3/cit/2.0" -N gco="http://standards.iso.org/iso/19115/-3/gco/1.0" \
--subnode "//mdb:distributionInfo/mrd:MD_Distribution" -t elem -n 'mrd:transferOptions' -v "" \
--subnode '$prev' -t elem -n 'mrd:MD_DigitalTransferOptions' -v "" \
--subnode '$prev' -t elem -n 'mrd:onLine' -v "" \
--subnode '$prev' -t elem -n 'cit:CI_OnlineResource' -v "" \
--subnode '$prev' -t elem -n 'cit:linkage' -v "" \
--subnode '$prev' -t elem -n 'gco:CharacterString' -v "https://doi.org/10.48784/15c8945c-534a-11ec-a1d1-02000a08f41d" \
--append  '($prev)[last()]' -t elem -n 'cit:protocol' -v '' \
--subnode '$prev' -t elem -n 'gco:CharacterString' -v "WWW:LINK-1.0-http--link" \
file.xsl

but the result is not correct. Could you tell me what I'm doing wrong?

CodePudding user response:

The $prev back reference is redefined by each -i, -a, and -s option so save the cit:CI_OnlineResource node in a variable:

  -s '$prev' -t elem -n 'cit:CI_OnlineResource' \
  --var CI '$prev' \
  -s '$CI' -t elem -n 'cit:linkage' \
  -s '$prev' -t elem -n 'gco:CharacterString' -v 'text' \
  # etc.

-s (--subnode) xpath adds a node as last child of xpath. Alternatively, use the -a (--append) option to append a sibling node.

  • Related