After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 86753 - allow multiple identical attribute in the same element
allow multiple identical attribute in the same element
Status: VERIFIED FIXED
Product: libxslt
Classification: Platform
Component: general
1.0.18
Other Linux
: Normal major
: ---
Assigned To: Daniel Veillard
Daniel Veillard
Depends on:
Blocks:
 
 
Reported: 2002-06-28 17:37 UTC by Marc-Olivier Bernard
Modified: 2009-08-15 18:40 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Marc-Olivier Bernard 2002-06-28 17:37:05 UTC
I take an xml file with some elements and attributes, and ask a
stylesheet to add existing attributes ; the output xml document
get thoses attributes twice.

____________________________________

consider todo.xml :

____________________________________

<?xml version="1.0" encoding="ISO-8859-1"?>
<todo>
  <domain id="id2588147" add="task" del="domain">
    <name id="id2588150" replace="PCDATA">job</name>
    <task id="id2588154" replace="PCDATA" add="task">to this</task>
    <task id="id2589156" replace="PCDATA" add="task">undefined</task>

  </domain>
  <domain id="id2588996" add="task" del="domain">
    <name id="id2588515" replace="PCDATA">courses</name>
    <task id="id2588931" replace="PCDATA" add="task">undefined</task>
  </domain>
</todo>

_______________________________________

and the following stylesheet (actions.xsl )
________________________________________



<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  >
  
  <xsl:output encoding="ISO-8859-1" method="xml"/>

  <xsl:variable name="targetId"></xsl:variable>
  <xsl:variable name="action"></xsl:variable>
  
  <xsl:template match="/">
    <xsl:apply-templates select="*|@*"/>
  </xsl:template>


  <xsl:template name="toto">
    <toto/>
  </xsl:template>


  <xsl:template name="add">
    <xsl:param name="type"/>
    
    <xsl:choose>
      <xsl:when test="$type = 'toto'">
        <xsl:call-template name="toto"/>
      </xsl:when>
    </xsl:choose>   
  </xsl:template>  

  <xsl:template name="copy">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template name="del">
    <!-- effacer ! -->
  </xsl:template>

  
  <xsl:template match="*[attribute::id and @id=$targetId]">
    <!-- attribute::type pour éviter de confondre l'absence d'attibute et
la valeur nulle -->
    <xsl:choose>
      <xsl:when test="$action='del'">
        <xsl:call-template name="del"/>
      </xsl:when>
      <xsl:when test="$action='add'">
        <xsl:call-template name="copy"/>
        <xsl:call-template name="add">
          <xsl:with-param name="type">toto</xsl:with-param>
        </xsl:call-template>
      </xsl:when>
      <xsl:when test="$action='repl'">
        <xsl:when test="$action='del'">
          <xsl:call-template name="del"/>
        </xsl:when>        
        <xsl:call-template name="add">
          <xsl:with-param name="type">toto</xsl:with-param>
        </xsl:call-template>
      </xsl:when>      
    </xsl:choose>
    
  </xsl:template>

  <!-- liste des elements qui peuvent être édités, donc attribut id -->

  <xsl:template match="domain">
    <xsl:copy>
      <xsl:if test="not(@id)">
      <xsl:attribute name="id"><xsl:value-of
select="generate-id()"/></xsl:attribute>
      </xsl:if>
      <xsl:attribute name="add">task</xsl:attribute>
      <xsl:attribute name="del">domain</xsl:attribute>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="name">
    <xsl:copy>
      <xsl:if test="not(@id)">
      <xsl:attribute name="id"><xsl:value-of
select="generate-id()"/></xsl:attribute>
      </xsl:if>
      <xsl:attribute name="replace">PCDATA</xsl:attribute>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>


  <xsl:template match="task">
    <xsl:copy>
      <xsl:if test="not(@id)">
      <xsl:attribute name="id"><xsl:value-of
select="generate-id()"/></xsl:attribute>
      </xsl:if>
      <xsl:attribute name="replace">PCDATA</xsl:attribute>
      <xsl:attribute name="add">task</xsl:attribute>	
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>



  <xsl:template match="*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  

  <xsl:template match="@*">
    <xsl:copy/>
  </xsl:template>
  
  
</xsl:stylesheet>
___________________________________________________

then  xsltproc -v action.xsl todo2.xml 

outputs :


Added namespace: xsl mapped to http://www.w3.org/1999/XSL/Transform
xsltPrecomputeStylesheet: removing ignorable blank node
xsltParseStylesheetProcess : found stylesheet
Registering global variable targetId
Defining global variable targetId
Registering global variable action
Defining global variable action
xsltCompilePattern : parsing '/'
xsltCompilePattern : parsed /, default priority 0.500000
added pattern : '/' priority 0.500000
xsltCompilePattern : parsing '*[attribute::id and @id=$targetId]'
xsltCompilePattern : parsed *[attribute::id and @id=$targetId], default
priority 0.500000
added pattern : '*[attribute::id and @id=$targetId]' priority 0.500000
xsltCompilePattern : parsing 'domain'
xsltCompilePattern : parsed domain, default priority 0.000000
added pattern : 'domain' priority 0.000000
xsltCompilePattern : parsing 'name'
xsltCompilePattern : parsed name, default priority 0.000000
added pattern : 'name' priority 0.000000
xsltCompilePattern : parsing 'task'
xsltCompilePattern : parsed task, default priority 0.000000
added pattern : 'task' priority 0.000000
xsltCompilePattern : parsing '*'
xsltCompilePattern : parsed *, default priority -0.500000
added pattern : '*' priority -0.500000
xsltCompilePattern : parsing '@*'
xsltCompilePattern : parsed @*, default priority -0.500000
added pattern : '@*' priority -0.500000
parsed 11 templates
Resolving attribute sets references
Initializing keys on todo2.xml
Registered 0 modules
Registering global variables
Registering global variables from action.xsl
Evaluating global variable targetId
Evaluating global variable action
xsltProcessOneNode: applying template '/' for /
xsltApplyTemplates: select *|@*
xsltApplyTemplates: list of 1 nodes
xsltEvalXPathPredicate: returns 0
xsltProcessOneNode: applying template '*' for todo
xsltCopy: node todo
xsltApplyTemplates: node: todo
xsltApplyTemplates: select node()|@*
xsltApplyTemplates: list of 5 nodes
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text 
  
Lookup variable targetId
found variable targetId
xsltEvalXPathPredicate: returns 0
xsltProcessOneNode: applying template 'domain' for domain
xsltCopy: node domain
xsltIf: test not(@id)
xsltIf: test evaluate to 0
xsltApplyOneTemplate: copy text task
xsltCopyText: copy text task
xsltApplyOneTemplate: copy text domain
xsltCopyText: copy text domain
xsltApplyTemplates: node: domain
xsltApplyTemplates: select node()|@*
xsltApplyTemplates: list of 10 nodes
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text 
    
Lookup variable targetId
found variable targetId
xsltEvalXPathPredicate: returns 0
xsltProcessOneNode: applying template 'name' for name
xsltCopy: node name
xsltIf: test not(@id)
xsltIf: test evaluate to 0
xsltApplyOneTemplate: copy text PCDATA
xsltCopyText: copy text PCDATA
xsltApplyTemplates: node: name
xsltApplyTemplates: select node()|@*
xsltApplyTemplates: list of 3 nodes
xsltProcessOneNode: applying template '@*' for attribute id
xsltCopy: attribute id
xsltProcessOneNode: applying template '@*' for attribute replace
xsltCopy: attribute replace
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text job
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text 
    
Lookup variable targetId
found variable targetId
xsltEvalXPathPredicate: returns 0
xsltProcessOneNode: applying template 'task' for task
xsltCopy: node task
xsltIf: test not(@id)
xsltIf: test evaluate to 0
xsltApplyOneTemplate: copy text PCDATA
xsltCopyText: copy text PCDATA
xsltApplyOneTemplate: copy text task
xsltCopyText: copy text task
xsltApplyTemplates: node: task
xsltApplyTemplates: select node()|@*
xsltApplyTemplates: list of 4 nodes
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text to this
xsltProcessOneNode: applying template '@*' for attribute id
xsltCopy: attribute id
xsltProcessOneNode: applying template '@*' for attribute replace
xsltCopy: attribute replace
xsltProcessOneNode: applying template '@*' for attribute add
xsltCopy: attribute add
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text 
    
Lookup variable targetId
found variable targetId
xsltEvalXPathPredicate: returns 0
xsltProcessOneNode: applying template 'task' for task
xsltCopy: node task
xsltIf: test not(@id)
xsltIf: test evaluate to 0
xsltApplyOneTemplate: copy text PCDATA
xsltCopyText: copy text PCDATA
xsltApplyOneTemplate: copy text task
xsltCopyText: copy text task
xsltApplyTemplates: node: task
xsltApplyTemplates: select node()|@*
xsltApplyTemplates: list of 4 nodes
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text undefined
xsltProcessOneNode: applying template '@*' for attribute id
xsltCopy: attribute id
xsltProcessOneNode: applying template '@*' for attribute replace
xsltCopy: attribute replace
xsltProcessOneNode: applying template '@*' for attribute add
xsltCopy: attribute add
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text 

  
xsltProcessOneNode: applying template '@*' for attribute id
xsltCopy: attribute id
xsltProcessOneNode: applying template '@*' for attribute add
xsltCopy: attribute add
xsltProcessOneNode: applying template '@*' for attribute del
xsltCopy: attribute del
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text 
  
Lookup variable targetId
found variable targetId
xsltEvalXPathPredicate: returns 0
xsltProcessOneNode: applying template 'domain' for domain
xsltCopy: node domain
xsltIf: test not(@id)
xsltIf: test evaluate to 0
xsltApplyOneTemplate: copy text task
xsltCopyText: copy text task
xsltApplyOneTemplate: copy text domain
xsltCopyText: copy text domain
xsltApplyTemplates: node: domain
xsltApplyTemplates: select node()|@*
xsltApplyTemplates: list of 8 nodes
xsltProcessOneNode: applying template '@*' for attribute id
xsltCopy: attribute id
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text 
    
Lookup variable targetId
found variable targetId
xsltEvalXPathPredicate: returns 0
xsltProcessOneNode: applying template 'name' for name
xsltCopy: node name
xsltIf: test not(@id)
xsltIf: test evaluate to 0
xsltApplyOneTemplate: copy text PCDATA
xsltCopyText: copy text PCDATA
xsltApplyTemplates: node: name
xsltApplyTemplates: select node()|@*
xsltApplyTemplates: list of 3 nodes
xsltProcessOneNode: applying template '@*' for attribute id
xsltCopy: attribute id
xsltProcessOneNode: applying template '@*' for attribute replace
xsltCopy: attribute replace
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text courses
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text 
    
Lookup variable targetId
found variable targetId
xsltEvalXPathPredicate: returns 0
xsltProcessOneNode: applying template 'task' for task
xsltCopy: node task
xsltIf: test not(@id)
xsltIf: test evaluate to 0
xsltApplyOneTemplate: copy text PCDATA
xsltCopyText: copy text PCDATA
xsltApplyOneTemplate: copy text task
xsltCopyText: copy text task
xsltApplyTemplates: node: task
xsltApplyTemplates: select node()|@*
xsltApplyTemplates: list of 4 nodes
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text undefined
xsltProcessOneNode: applying template '@*' for attribute id
xsltCopy: attribute id
xsltProcessOneNode: applying template '@*' for attribute replace
xsltCopy: attribute replace
xsltProcessOneNode: applying template '@*' for attribute add
xsltCopy: attribute add
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text 
  
xsltProcessOneNode: applying template '@*' for attribute add
xsltCopy: attribute add
xsltProcessOneNode: applying template '@*' for attribute del
xsltCopy: attribute del
xsltProcessOneNode: no template found for text
xsltDefaultProcessOneNode: copy text 

and :

<?xml version="1.0" encoding="ISO-8859-1"?>
<todo>
  <domain add="task" del="domain" id="id2588147" add="task" del="domain">
          ^^^^^^^^^^                             ^^^^^^^^^^
    <name replace="PCDATA" id="id2588150" replace="PCDATA">job</name>
          ^^^^^^^^^^^^^^^^                ^^^^^^^^^^^^^^^^etc.
    <task replace="PCDATA" add="task" id="id2588154" replace="PCDATA"
add="task">to this</task>
    <task replace="PCDATA" add="task" id="id2589156" replace="PCDATA"
add="task">undefined</task>

  </domain>
  <domain add="task" del="domain" id="id2588996" add="task" del="domain">
    <name replace="PCDATA" id="id2588515" replace="PCDATA">courses</name>
    <task replace="PCDATA" add="task" id="id2588931" replace="PCDATA"
add="task">undefined</task>
  </domain>
</todo>

Marc-Olivier Bernard
__________________________________________________
xsltproc -V
Using libxml 20422, libxslt 10018 and libexslt 709
xsltproc was compiled against libxml 20419, libxslt 10018 and libexslt 709
libxslt 10018 was compiled against libxml 20419
libexslt 709 was compiled against libxml 20419
Comment 1 Daniel Veillard 2002-07-05 20:16:22 UTC
Hum, right ooops ... the bug was on xsl:copy on an attribute !
This is now fixed in CVS:

gnome:~/XSLT/tests/general -> xsltproc bug-89.xsl ../docs/bug-89.xml 
<?xml version="1.0" encoding="ISO-8859-1"?>
<todo>
<domain add="task" del="domain" id="id2588147">
<name replace="PCDATA" id="id2588150">job</name>
<task replace="PCDATA" add="task" id="id2588154">to this</task>
<task replace="PCDATA" add="task" id="id2589156">undefined</task>
</domain>
<domain add="task" del="domain" id="id2588996">
<name replace="PCDATA" id="id2588515">courses</name>
<task replace="PCDATA" add="task" id="id2588931">undefined</task>
</domain>
</todo>
gnome:~/XSLT/tests/general -> 

  thanks for the report and the test case !

Daniel
Comment 2 Daniel Veillard 2002-08-27 10:11:24 UTC
Okay, this should be fixed in the last releases,

Daniel