2017-09-19 2 views
0

J'ai déjà un nouveau problème. Je dois fusionner des listes via xsl, le problème est que la clé dans la liste de recherche doit être concaténée par 2 valeurs. Les listes peuvent être relativement grandes avec des milliers, dix-milliers dans certains cas encore plus d'entrées dans les deux listes. En avance sur les grandes tailles de cette liste, je dois regarder la performance et la mémoire. Il se pourrait que cela soit implémenté plus tard dans un client de service web, il doit donc fonctionner rapidement et économiser des ressources.XSL pour chaque filtre avec sous-contexte d'un autre nœud principal

Fusionner les éléments existants dans List1 et List2 est fait et n'a pas été compliqué, mais maintenant je dois vérifier les deux listes sur les éléments non existants dans l'autre liste. J'ai essayé d'annuler l'instruction select-for-each, mais j'ai échoué et c'est vraisemblablement dans le mauvais sens.

InputXML-exemple

<ROOT> 
    <getObjectListResponse> 
     <item> 
      <Key>1111111:aaaa</Key> 
      <someOhterData>Text</someOhterData> 
     </item> 
     <item> 
      <Key>2222222:bbbb</Key> 
      <someOhterData>Text</someOhterData> 
     </item> 
     <item> 
      <Key>3333333:aaaa</Key> 
      <someOhterData>Text</someOhterData> 
     </item> 
    </getObjectListResponse> 
    <LookupList> 
     <DATA> 
      <KeyPart1>1111111</KeyPart1> 
      <KeyPart2>aaaa</KeyPart2> 
      <someOhterData>Text</someOhterData> 
     </DATA> 
     <DATA> 
      <KeyPart1>1111111</KeyPart1> 
      <KeyPart2>bbbb</KeyPart2> 
      <someOhterData>Text</someOhterData> 
     </DATA> 
     <DATA> 
      <KeyPart1>2222222</KeyPart1> 
      <KeyPart2>aaaa</KeyPart2> 
      <someOhterData>Text</someOhterData> 
     </DATA> 
     <DATA> 
      <KeyPart1>2222222</KeyPart1> 
      <KeyPart2>bbbb</KeyPart2> 
      <someOhterData>Text</someOhterData> 
     </DATA> 
     <DATA> 
      <KeyPart1>3333333</KeyPart1> 
      <KeyPart2>aaaa</KeyPart2> 
      <someOhterData>Text</someOhterData> 
     </DATA> 
     <DATA> 
      <KeyPart1>3333333</KeyPart1> 
      <KeyPart2>bbbb</KeyPart2> 
      <someOhterData>Text</someOhterData> 
     </DATA> 
    </LookupList> 
</ROOT> 

La première partie, trouver les pièces existantes dans les deux listes est déjà fait. La deuxième partie est de trouver des parties inexistantes dans la liste 1 à la liste 2 et la liste 2 à la liste 1. Je veux faire cela dans for-each, donc vous obtenez seulement des entrées non-existantes de List1 qui n'existe pas dans List2. Mon problème est de rechercher dans chaque contexte avec une clé concaténée, à partir de toutes les données dans LookupList.

<xsl:for-each select="/*/getObjectListResponse/item[Key/text() != /*/LookupList/DATA/*[concat(KeyPart1,'/',KeyPart2)]]"> 
       <xsl:copy-of select="."/>   
      </xsl:for-each> 

<xsl:for-each select="/*/getObjectListResponse/item[Key/text() != /*/LookupList/DATA/[concat(KeyPart1,'/',KeyPart2)]]"> 
       <xsl:copy-of select="."/>   
      </xsl:for-each>  

Mais tout ce que j'ai essayé échoue, sans résultat ou mauvais résultat.

Comment cela peut-il être fait?

J'ai essayé ceci et quelques autres, mais rien ne fonctionnera.

Merci à l'avance

Répondre

2

J'utiliser des clés pour la référence croisée, voici un XSLT 3.0 (comme soutenu par Saxon 9.8 toutes les éditions ou Altova XMLSpy/Raptor) stylesheet comme évidemment un échantillon est un bon cas d'utilisation pour une clé composite:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" 
    exclude-result-prefixes="xs math" 
    version="3.0"> 

    <xsl:output indent="yes"/> 

    <xsl:key name="data" match="DATA" composite="true" use="KeyPart1, KeyPart2"/> 

    <xsl:key name="item" match="item" use="Key"/> 

    <xsl:template match="ROOT"> 
     <xsl:copy> 
      <items-not-in-data> 
       <xsl:copy-of select="getObjectListResponse/item[not(key('data', (substring-before(Key, ':'), substring-after(Key, ':'))))]"/> 
      </items-not-in-data> 
      <data-not-in-items> 
       <xsl:copy-of select="LookupList/DATA[not(key('item', concat(KeyPart1, ':', KeyPart2)))]"/> 
      </data-not-in-items> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

pour vos données d'exemple que je reçois

<ROOT> 
    <items-not-in-data/> 
    <data-not-in-items> 
     <DATA> 
           <KeyPart1>1111111</KeyPart1> 
           <KeyPart2>bbbb</KeyPart2> 
           <someOhterData>Text</someOhterData> 
        </DATA> 
     <DATA> 
           <KeyPart1>2222222</KeyPart1> 
           <KeyPart2>aaaa</KeyPart2> 
           <someOhterData>Text</someOhterData> 
        </DATA> 
     <DATA> 
           <KeyPart1>3333333</KeyPart1> 
           <KeyPart2>bbbb</KeyPart2> 
           <someOhterData>Text</someOhterData> 
        </DATA> 
    </data-not-in-items> 
</ROOT> 

de XSLT 3.0 et bien sûr une clé composite n'est pas obligatoire, vous pourriez aussi bien utiliser XSLT 2.0 et utilisez une seule valeur de clé concat(KeyPart1, KeyPart2).

+0

essayé et fonctionne bien, merci beaucoup. –