XSL does not work. The loop in the loop is incorrectly done. Tell me please.

Here is my xml:

<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE database SYSTEM 'xmlschemas/domino_9_0_1.dtd'> <database xmlns='http://www.lotus.com/dxl' version='9.0' maintenanceversion='1.8' replicaid='4525808B002B756C' path='sed\gecho\gecho_intgr.nsf' title='Госэкспертиза. Интеграция' fromtemplate='osn_tmpl_int' increasemaxfields='true'> <database> <document form='Request'> <item name='noteid'><text>4CA5A</text></item> </document> <document form='Request'> <item name='noteid'><text>23953A</text></item> </document> <document form='Report'> <item name='obj_exp'> <textlist> <text>4CA5A:Нагорная А.Н.</text> <text>5CA9A:Иванов С.С.</text> <text>23953A:Носков И.Н.</text> </textlist> </item> </document> </database> 

Here is my xslt

 <xsl:for-each select="dxl:database/dxl:document[@form='Request']/dxl:item[@name='noteid']"> <xsl:for-each select="dxl:database/dxl:document/dxl:item[@name='obj_exp']/dxl:textlist/dxl:text"> <xsl:if test="dxl:database/dxl:document[@form='Request']/dxl:item[@name='noteid']='dxl:database/dxl:document/dxl:item[@name='obj_exp']/dxl:textlist/dxl:text'"> <xsl:value-of select="substring-after(text,':')"/> </xsl:if> </xsl:for-each> </xsl:for-each> 
  • The xml shown has no namespaces. Meanwhile, xslt has the prefix dxl . What is it equal to? Give more information. - Alexander Petrov
  • @AlexanderPetrov added a namespace in xml (xmlns = ' lotus.com/dxl' ) dxl is a prefix that indicates that the conversion does not go with pure xml, but with dxl. DXL is Domino XML in the IBM Notes system - Maxim Buriak

1 answer 1

 <xsl:for-each select="dxl:database/dxl:document[@form='Request']/dxl:item[@name='noteid']"> <xsl:variable name="id" select="./dxl:text"/> <xsl:for-each select="/dxl:database/dxl:document/dxl:item[@name='obj_exp']/dxl:textlist/dxl:text"> <xsl:if test="$id=substring-before(.,':')"> <xsl:value-of select="substring-after(.,':')"/> </xsl:if> </xsl:for-each> </xsl:for-each> 

Character . (dot) means current node. In the first cycle, we memorize its value in a variable.

Within the second cycle, the point will already indicate its nodes.

We also start the second cycle from the root - at the beginning xpath we add / . Otherwise, the counting will be conducted from the current node of the first cycle.

Inside if compare the value of the saved variable with the value of the current node of the nested loop.

I hope everything is clear.


A better approach for this is to use key . In essence, this is a dictionary (associative array, hash table, dictionary).

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dxl="http://www.lotus.com/dxl"> <xsl:key name="list" match="dxl:database/dxl:document/dxl:item[@name='obj_exp']/dxl:textlist/dxl:text" use="substring-before(.,':')"/> <xsl:template match="/"> <xsl:for-each select="dxl:database/dxl:document[@form='Request']/dxl:item[@name='noteid']"> <xsl:value-of select="substring-after(key('list', .), ':')"/> </xsl:for-each> </xsl:template> </xsl:stylesheet> 

Brought the entire stylesheet completely, so that it was clear where the key is set — outside of any template (template), at the top level.

Extraction from the dictionary using the key('list', .) Function happens very quickly, which significantly improves performance (this is noticeable for large volumes).