Learner5
Learner5

Reputation: 17

XSLT: An attribute node (ana) cannot be created after a child of the containing element

I have been trying to apply an XSL to my XML but I keep getting the error: An attribute node (ana) cannot be created after a child of the containing element. in line 25 of the XSL. It appears to be a problem with the element "ana" but I haven't been able to find the right solution yet.

This is my XML:

<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <teiHeader>
  <fileDesc>
     <titleStmt>
        <title>number of the XML</title>
        <author>Myname</author>
     </titleStmt>
     <editionStmt>
        <edition>
           <date>2018-12-20</date>
        </edition>
     </editionStmt>
     <publicationStmt>
        <p>unknown</p>
     </publicationStmt>
     <sourceDesc>
        <p>Converted from a Word document</p>
     </sourceDesc>
  </fileDesc>
  <encodingDesc>
     <appInfo>
        <application xml:id="docxtotei" ident="TEI_fromDOCX" version="2.15.0">
           <label>DOCX to TEI</label>
        </application>
     </appInfo>
  </encodingDesc>
  <revisionDesc>
     <listChange>
        <change>
           <date>2021-05-21T15:08:01Z</date>
           <name>MyName</name>
        </change>
     </listChange>
  </revisionDesc>
 </teiHeader>

And this is my XSL:

       <?xml version="1.0" encoding="UTF-8"?>
       <xsl:stylesheet version="1.0"  xmlns="http://www.tei-c.org/ns/1.0"   
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/">
    <TEI>
        <xsl:variable name="xml_id" select="/TEI/teiHeader/encodingDesc/appInfo/application/@xml:id"/>
        <!-- The variable xml_id can be used for further processing.  -->   
        <xsl:attribute name="xml:id"><xsl:value-of select="'Project-CT'"/></xsl:attribute>
        <xsl:attribute name="xml:lang"><xsl:value-of select="'ca'"/></xsl:attribute>
        <teiHeader>
            <fileDesc>
                <titleStmt>
                    <xsl:for-each select="/TEI/teiHeader/fileDesc/titleStmt/title">
                        <title>
                            <xsl:variable name="xml_lang" select="'ca'"/>
                            <!-- The variable xml_lang can be used for further processing.  -->
                            
                            
                            <xsl:attribute name="xml:lang"><xsl:value-of select="'ca'"/></xsl:attribute>
                            <xsl:attribute name="rend"><xsl:value-of select="'main'"/></xsl:attribute>
                        </title>
                    </xsl:for-each>
                    <xsl:for-each select=".">
                        <meeting>
                            <xsl:value-of   select="'num sessió'"/>
                            <xsl:attribute name="ana"><xsl:value-of select="'#parla session'"/></xsl:attribute>
                            <xsl:attribute name="corresp"><xsl:value-of select="'#PC'"/></xsl:attribute>
                            <xsl:attribute name="n"><xsl:value-of select="'X'"/></xsl:attribute>
                        </meeting>
                    </xsl:for-each>
                    <respStmt>
                        <persName>
                            <xsl:value-of   select="'MyName'"/>
                        </persName>
                        <xsl:for-each select=".">
                            <resp>
                                <xsl:value-of   select="'Data retrieval and conversion to XML'"/>
                                <xsl:variable name="xml_lang" select="'en'"/>
                                <!-- The variable xml_lang can be used for further processing.  -->
                                
                                
                                <xsl:attribute name="xml:lang"><xsl:value-of select="'ca'"/></xsl:attribute>
                            </resp>
                        </xsl:for-each>
                    </respStmt>
                    <funder>
                        <xsl:for-each select=".">
                            <orgName>
                                <xsl:value-of   select="'Cap financiació'"/>
                                <xsl:variable name="xml_lang" select="'ca'"/>
                                <!-- The variable xml_lang can be used for further processing.  -->
                                
                                
                                <xsl:attribute name="xml:lang"><xsl:value-of select="'en'"/></xsl:attribute>
                            </orgName>
                        </xsl:for-each>
                    </funder>
                </titleStmt>
                <editionStmt>
                    <xsl:for-each select="/TEI/teiHeader/fileDesc/editionStmt/edition">
                        <edition>
                            <xsl:value-of   select="."/>
                        </edition>
                    </xsl:for-each>
                </editionStmt>
                <extent>
                    <xsl:for-each select=".">
                        <measure>
                            <xsl:value-of   select="'X intervencions'"/>
                            <xsl:variable name="xml_lang" select="'ca'"/>
                            <!-- The variable xml_lang can be used for further processing.  -->
                            
                            
                            <xsl:attribute name="xml:lang"><xsl:value-of select="'en'"/></xsl:attribute>
                            <xsl:attribute name="quantity"><xsl:value-of select="'X'"/></xsl:attribute>
                            <xsl:attribute name="unit"><xsl:value-of select="'speeches'"/></xsl:attribute>
                        </measure>
                    </xsl:for-each>
                </extent>
                <publicationStmt>
                    <publisher>
                        <xsl:for-each select=".">
                            <orgName>
                                <xsl:value-of   select="'NameProject'"/>
                                <xsl:variable name="xml_lang" select="'ca'"/>
                                <!-- The variable xml_lang can be used for further processing.  -->
                                
                                
                                <xsl:attribute name="xml:lang"><xsl:value-of select="'en'"/></xsl:attribute>
                            </orgName>
                        </xsl:for-each>
                        <ref>
                            <xsl:value-of   select="'URL'"/>
                            <xsl:variable name="target" select="'URL'"/>
                            <!-- The variable target can be used for further processing.  -->
                            
                            
                            <xsl:attribute name="target"><xsl:value-of select="$target"/></xsl:attribute>
                        </ref>
                    </publisher>
                    <idno>
                        <xsl:value-of   select="'http://hdl.handle.net/11356/1388'"/>
                        <xsl:variable name="rend" select="'URI'"/>
                        <!-- The variable rend can be used for further processing.  -->
                        
                        
                        <xsl:attribute name="rend"><xsl:value-of select="$rend"/></xsl:attribute>
                        <xsl:attribute name="subrend"><xsl:value-of select="'handle'"/></xsl:attribute>
                    </idno>
                    <availability>
                        <xsl:variable name="status" select="'free'"/>
                        <!-- The variable status can be used for further processing.  -->
                        
                        
                        <xsl:attribute name="status"><xsl:value-of select="$status"/></xsl:attribute>
                        <licence>
                            <xsl:value-of   select="'http://creativecommons.org/licenses/by/4.0/'"/>
                        </licence>
                        <xsl:for-each select="/TEI/teiHeader/fileDesc/publicationStmt/p">
                            <p>
                                <xsl:value-of   select="."/>
                                <xsl:variable name="xml_lang" select="'ca'"/>
                                <!-- The variable xml_lang can be used for further processing.  -->
                                
                                
                                <xsl:attribute name="xml:lang"><xsl:value-of select="'en'"/></xsl:attribute>
                                <ref>
                                    <xsl:value-of   select="'Atribución 4.0 Internacional'"/>
                                    <xsl:variable name="target" select="'https://creativecommons.org/licenses/by/4.0/'"/>
                                    <!-- The variable target can be used for further processing.  -->
                                    
                                    
                                    <xsl:attribute name="target"><xsl:value-of select="$target"/></xsl:attribute>
                                </ref>
                            </p>
                        </xsl:for-each>
                    </availability>
                    <date>
                        <xsl:value-of   select="/TEI/teiHeader/fileDesc/editionStmt/edition/date"/>
                        <xsl:variable name="when" select="'2021'"/>
                        <!-- The variable when can be used for further processing.  -->
                        
                        
                        <xsl:attribute name="when"><xsl:value-of select="$when"/></xsl:attribute>
                    </date>
                </publicationStmt>
                <sourceDesc>
                    <bibl>
                        <xsl:for-each select="/TEI/teiHeader/fileDesc/titleStmt/title">
                            <title>
                                <xsl:value-of   select="."/>
                                <xsl:variable name="xml_lang" select="'ca'"/>
                                <!-- The variable xml_lang can be used for further processing.  -->
                                
                                
                                <xsl:attribute name="xml:lang"><xsl:value-of select="'en'"/></xsl:attribute>
                                <xsl:attribute name="rend"><xsl:value-of select="'main'"/></xsl:attribute>
                            </title>
                        </xsl:for-each>
                        <idno>
                            <xsl:value-of   select="'URL'"/>
                            <xsl:variable name="rend" select="'URI'"/>
                            <!-- The variable rend can be used for further processing.  -->
                            
                            
                            <xsl:attribute name="rend"><xsl:value-of select="$rend"/></xsl:attribute>
                        </idno>
                        <date>
                            <xsl:value-of   select="/TEI/teiHeader/fileDesc/editionStmt/edition/date"/>
                            <xsl:variable name="from" select="'data sessió'"/>
                            <!-- The variable from can be used for further processing.  -->
                            
                            
                            <xsl:attribute name="from"><xsl:value-of select="$from"/></xsl:attribute>
                            <xsl:attribute name="to"><xsl:value-of select="'data sessió'"/></xsl:attribute>
                        </date>
                    </bibl>
                </sourceDesc>
            </fileDesc>
            <encodingDesc>
                <projectDesc>
                    <xsl:for-each select="/TEI/teiHeader/fileDesc/publicationStmt/p">
                        <p>
                            <xsl:variable name="xml_lang" select="'ca'"/>
                            <!-- The variable xml_lang can be used for further processing.  -->
                            
                            
                            <xsl:attribute name="xml:lang"><xsl:value-of select="'en'"/></xsl:attribute>
                            <ref>
                                <xsl:value-of   select="'NameProject'"/>
                                <xsl:variable name="target" select="'URL'"/>
                                <!-- The variable target can be used for further processing.  -->
                                
                                
                                <xsl:attribute name="target"><xsl:value-of select="$target"/></xsl:attribute>
                            </ref>
                        </p>
                    </xsl:for-each>
                </projectDesc>
                <tagsDecl>
                    <namespace>
                        <xsl:variable name="name" select="/TEI/teiHeader/revisionDesc/listChange/change/name"/>
                        <!-- The variable name can be used for further processing.  -->
                        
                        
                        <xsl:attribute name="name"><xsl:value-of select="$name"/></xsl:attribute>
                        <xsl:for-each select=".">
                            <tagUsage>
                                <xsl:attribute name="gi"><xsl:value-of select="'body'"/></xsl:attribute>
                                <xsl:attribute name="occurs"><xsl:value-of select="'X'"/></xsl:attribute>
                            </tagUsage>
                        </xsl:for-each>
                    </namespace>
                </tagsDecl>
            </encodingDesc>
            <profileDesc>
                <settingDesc>
                    <xsl:for-each select="/TEI/teiHeader/revisionDesc/listChange/change">
                        <setting>
                            <xsl:for-each select="./name">
                                <name>
                                    <xsl:value-of   select="."/>
                                    <xsl:attribute name="rend"><xsl:value-of select="'address'"/></xsl:attribute>
                                </name>
                            </xsl:for-each>
                            <date>
                                <xsl:value-of   select="./TEI/teiHeader/fileDesc/editionStmt/edition/date"/>
                                <xsl:variable name="date" select="$date"/>
                                <!-- The variable from can be used for further processing.  -->
                                
                                
                                <xsl:attribute name="date"><xsl:value-of select="$date"/></xsl:attribute>
                                <xsl:attribute name="date"><xsl:value-of select="$date"/></xsl:attribute>
                            </date>
                        </setting>
                    </xsl:for-each>
                </settingDesc>
            </profileDesc>
        </teiHeader>
    </TEI>
</xsl:template>
</xsl:stylesheet>

And the desired output would be like this: (Just to point out there is some data present on the desired output that doesn't appear in the root XML)

<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:lang="ca" xml:id="ProjectName">
<teiHeader>
  <fileDesc>
     <titleStmt>
        <title rend="main" xml:lang="ca"></title>
        <title rend="main" xml:lang="en"></title>
        <title rend="sub" xml:lang="ca"></title>
        <title rend="sub" xml:lang="en"></title>
         <meeting n="X" corresp="#PC" ana="#parla.session">num sessió</meeting>
        <meeting n="X" corresp="#PC" ana="#parla.term #PC.">num legislatura</meeting>
        <respStmt>
           <persName>Myname</persName>
           <resp xml:lang="en">Data retrieval and conversion to XML</resp>
        </respStmt>
        <funder>
           <orgName xml:lang="ca">Cap financiació  </orgName>
           <orgName xml:lang="en">No funder</orgName>
        </funder>
     </titleStmt>
     <editionStmt>
        <edition>1.0</edition>
     </editionStmt>
     <extent><!--These numbers do not reflect the size of the sample!-->
        <measure unit="speeches" quantity="X" xml:lang="ca">X intervencions</measure>
        <measure unit="speeches" quantity="X" xml:lang="en">X speeches</measure>
        <measure quantity="X" unit="words" xml:lang="ca">X paraules</measure>
        <measure quantity="X" unit="words" xml:lang="en">X words</measure>
     </extent>
     <publicationStmt>
        <publisher>
           <orgName xml:lang="ca">ProjectOrg</orgName>
           <orgName xml:lang="en">Projectorg</orgName>
           <ref target="URL"</ref>
        </publisher>
        <idno rend="URI" subrend="handle">http://hdl.handle.net/11356/1388</idno>
        <availability status="free">
        </availability>
        <date when="2021">2021</date>
     </publicationStmt>
     <sourceDesc>
        <bibl>
           <title xml:lang="ca" rend="main">Discursos</title>
           <title rend="main" xml:lang="en">Speeches</title>
           <idno rend="URI">https://www.parlament.cat/</idno>
           <date from="date" to="date">date -date</date>
        </bibl>
     </sourceDesc>
  </fileDesc>
  <encodingDesc>
     <projectDesc>
        <p xml:lang="ca">
           <ref target="URL">ProjectName</ref>
        </p>
        <p xml:lang="en">
           <ref target="URL">ProjectName</ref></p>
     </projectDesc>
     <tagsDecl><!--These numbers do not reflect the size of the sample!-->
        <namespace name="http://www.tei-c.org/ns/1.0">
           <tagUsage gi="body" occurs="X"/>
           <tagUsage gi="pb" occurs="X"/>
           <tagUsage gi="div" occurs="X"/>
           <tagUsage gi="head" occurs="X"/>
           <tagUsage gi="note" occurs="X"/>
           <tagUsage gi="u" occurs="X"/>
           <tagUsage gi="seg" occurs="X"/>
        </namespace>
     </tagsDecl>
   </encodingDesc>
   <profileDesc>
     <settingDesc>
        <setting>
           <name rend="address">Adress</name>
           <name rend="city">Barcelona</name>
           <name rend="country" key="ES">Spain</name>
           <date from="2015-10-26" to="2020-12-18">26.10.2015 - 18.12.2020</date>
        </setting>
     </settingDesc>
  </profileDesc>

Upvotes: 0

Views: 238

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116982

The error message you report is quite clear: adding an attribute to an element after children have been added to it is an error:
https://www.w3.org/TR/1999/REC-xslt-19991116/#creating-attributes

That means that instead of:

                    <meeting>
                        <xsl:value-of   select="'num sessió'"/>
                        <xsl:attribute name="ana"><xsl:value-of select="'#parla session'"/></xsl:attribute>
                        <xsl:attribute name="corresp"><xsl:value-of select="'#PC'"/></xsl:attribute>
                        <xsl:attribute name="n"><xsl:value-of select="'X'"/></xsl:attribute>
                    </meeting>

you need to do:

                    <meeting>
                        <xsl:attribute name="ana"><xsl:value-of select="'#parla session'"/></xsl:attribute>
                        <xsl:attribute name="corresp"><xsl:value-of select="'#PC'"/></xsl:attribute>
                        <xsl:attribute name="n"><xsl:value-of select="'X'"/></xsl:attribute>
                        <xsl:value-of   select="'num sessió'"/>
                    </meeting>

And likewise, instead of:

                        <resp>
                            <xsl:value-of   select="'Data retrieval and conversion to XML'"/>
                            <xsl:variable name="xml_lang" select="'en'"/>
                            <!-- The variable xml_lang can be used for further processing.  -->
                            
                            
                            <xsl:attribute name="xml:lang"><xsl:value-of select="'ca'"/></xsl:attribute>
                        </resp>

you need:

                        <resp>
                            <xsl:attribute name="xml:lang"><xsl:value-of select="'ca'"/></xsl:attribute>
                            <xsl:value-of   select="'Data retrieval and conversion to XML'"/>
                            <xsl:variable name="xml_lang" select="'en'"/>
                            <!-- The variable xml_lang can be used for further processing.  -->
                            
                            
                        </resp>

and so on for the rest of your stylesheet (I will not go over 241 lines (!) of code).

Note also that the XML you show us is in a namespace which your XSLT completely ignores. As a result, none of your XPath expressions will select anything in the source XML - see: https://stackoverflow.com/a/34762628/3016153


BTW, the instruction:

<xsl:attribute name="ana"><xsl:value-of select="'#parla session'"/></xsl:attribute>

can be simplified to:

<xsl:attribute name="ana">#parla session</xsl:attribute>

and the entire block could be reduced to a single literal result element:

<meeting ana="#parla session" corresp="#PC" n="X">num sessió</meeting>

In addition, doing:

<xsl:for-each select=".">

is entirely redundant: there is only one current node.

Upvotes: 2

Related Questions