2012-05-01 4 views
1

Un problème actuel que je suis en train de résoudre génère une comparaison de deux fichiers XML avec des différences et des similitudes via xslt.Passant Xml Snippet en xslt en tant que paramètre

Par exemple, le premier fichier xml ressemble

<?xml version="1.0" encoding="utf-8" ?> 
<Stats Date="2011-01-01"> 
    <Player Rank="1"> 
    <GP>39</GP> 
    <G>32</G> 
    <A>33</A> 
    <PlusMinus>20</PlusMinus> 
    <PIM>29</PIM> 
    <PP>10</PP> 
    <SH>1</SH> 
    <GW>3</GW> 
    <Shots>0</Shots> 
    <ShotPctg>154</ShotPctg> 
    <TOIPerGame>20.8</TOIPerGame> 
    <ShiftsPerGame>21:54</ShiftsPerGame> 
    <FOWinPctg>22.6</FOWinPctg> 
    </Player> 
</Stats> 

Le second fichier ressemble

<?xml version="1.0" encoding="utf-8" ?> 
<Stats Date="2011-01-01"> 
    <Player Rank="2"> 
    <Name>John Smith</Name> 
    <Team>NY</Team> 
    <Pos>D</Pos> 
    <GP>38</GP> 
    <G>32</G> 
    <A>33</A> 
    <PlusMinus>15</PlusMinus> 
    <PIM>29</PIM> 
    <PP>10</PP> 
    <SH>1</SH> 
    <GW>4</GW> 
    <Shots>0</Shots> 
    <ShotPctg>158</ShotPctg> 
    <TOIPerGame>20.8</TOIPerGame> 
    <ShiftsPerGame>21:54</ShiftsPerGame> 
    <FOWinPctg>22.6</FOWinPctg> 
    </Player> 
</Stats> 

Quand je Noyez le second fichier dans le xslt déposer les œuvres de sortie comme prévu:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:param name="vrtfDoc2"> 
    <Stats Date="2011-01-01"> 
     <Player Rank="2"> 
     <Name>John Smith</Name> 
     <Team>NY</Team> 
     <Pos>D</Pos> 
     <GP>38</GP> 
     <G>32</G> 
     <A>33</A> 
     <PlusMinus>15</PlusMinus> 
     <PIM>29</PIM> 
     <PP>10</PP> 
     <SH>1</SH> 
     <GW>4</GW> 
     <Shots>0</Shots> 
     <ShotPctg>158</ShotPctg> 
     <TOIPerGame>20.8</TOIPerGame> 
     <ShiftsPerGame>21:54</ShiftsPerGame> 
     <FOWinPctg>22.6</FOWinPctg> 
     </Player> 
    </Stats> 
    </xsl:param> 

    <xsl:variable name="vDoc2" select= 
    "document('')/*/xsl:param[@name='vrtfDoc2']/*"/> 

    <xsl:template match="node()|@*" name="identity"> 
    <xsl:param name="pDoc2"/> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"> 
     <xsl:with-param name="pDoc2" select="$pDoc2"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="*"> 
     <xsl:with-param name="pDoc2" select="$vDoc2"/> 
    </xsl:apply-templates> 

    ----------------------- 

    <xsl:apply-templates select="$vDoc2"> 
     <xsl:with-param name="pDoc2" select="/*"/> 
    </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="Player/*"> 
    <xsl:param name="pDoc2"/> 
    <xsl:if test= 
    "not(. = $pDoc2/*/*[name()=name(current())])"> 
     <xsl:call-template name="identity"/> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="Name|Team|Pos" priority="20"/> 
</xsl:stylesheet> 

lorsque vous utilisez le code C# suivant:

private string Transform(string xml, string xml2, string xsl) { 
      StringWriter writer = new StringWriter(); 
      XslCompiledTransform t = new XslCompiledTransform(true); 
      XsltSettings settings = new XsltSettings(true, false); 
      XmlTextReader xmlReader = new XmlTextReader(xml); 

      XmlTextReader xslReader = new XmlTextReader(xsl); 
      t.Load(xslReader, settings, null); 

      t.Transform(xmlReader, null, writer); 
      return writer.ToString(); 
     } 

Lorsque je supprime le fichier XML intégré de la xslt

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:param name="vrtfDoc2" /> 

    <xsl:variable name="vDoc2" select= 
    "document('')/*/xsl:param[@name='vrtfDoc2']/*"/> 

    <xsl:template match="node()|@*" name="identity"> 
    <xsl:param name="pDoc2"/> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"> 
     <xsl:with-param name="pDoc2" select="$pDoc2"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="*"> 
     <xsl:with-param name="pDoc2" select="$vDoc2"/> 
    </xsl:apply-templates> 

    ----------------------- 

    <xsl:apply-templates select="$vDoc2"> 
     <xsl:with-param name="pDoc2" select="/*"/> 
    </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="Player/*"> 
    <xsl:param name="pDoc2"/> 
    <xsl:if test= 
    "not(. = $pDoc2/*/*[name()=name(current())])"> 
     <xsl:call-template name="identity"/> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="Name|Team|Pos" priority="20"/> 
</xsl:stylesheet> 

Le changement de la méthode C# pour

private string Transform(string xml, string xml2, string xsl) { 
      StringWriter writer = new StringWriter(); 
      XslCompiledTransform t = new XslCompiledTransform(true); 
      XsltSettings settings = new XsltSettings(true, false); 
      XmlTextReader xmlReader = new XmlTextReader(xml); 

      XmlDocument doc1 = new XmlDocument(); 
      // populate as needed e.g. 
      doc1.Load(xml2); 

      XmlTextReader xslReader = new XmlTextReader(xsl); 
      t.Load(xslReader, settings, null); 

      //Pass parameter value to xslt from code 
      XsltArgumentList argumentList = new XsltArgumentList(); 
      argumentList.AddParam("vrtfDoc2", "", doc1); 
      t.Transform(xmlReader, argumentList, writer); 
      return writer.ToString(); 
     } 

Je reçois une sortie vierge de la transformation, pour la vie de moi, je Je n'arrive pas à comprendre pourquoi. Je l'ai fait un pas dans les deux versions en utilisant le débogueur et la valeur du paramètre semble identique dans les deux occassions, mais lorsque le paramètre la version passée frappe l'extrait suivant dans le xslt pas de transformation se produit:

<xsl:apply-templates select="$vDoc2"> 
     <xsl:with-param name="pDoc2" select="/*"/> 
    </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="Player/*"> 
    <xsl:param name="pDoc2"/> 
    <xsl:if test= 
    "not(. = $pDoc2/*/*[name()=name(current())])"> 
     <xsl:call-template name="identity"/> 
    </xsl:if> 
    </xsl:template> 

Toute aide ou suggestions seraient beaucoup apprécié.

Répondre

4

Le problème est dans ce code:

<xsl:param name="vrtfDoc2" />  

    <xsl:variable name="vDoc2" select= 
    "document('')/*/xsl:param[@name='vrtfDoc2']/*"/> 

Cette analyse du fichier qui contient la feuille de style XSLT, localise le globa; xsl:param qui a name attribut avec valeur de chaîne "vrtfDoc2" et sélectionne les éléments enfants de cette xsl:param - mais il n'a pas d'enfant, donc la valeur de $vDoc2 est le vide node-set.

Solution:

Utilisez simplement:

<xsl:variable name="vDoc2" select="$vrtfDoc2/*"/> 

Remarques sur la dénomination:

S'il vous plaît renommer le paramètre comme son nom actuel est source de confusion et induire en erreur:

  1. Utilisez des noms commençant par p pour les paramètres et les noms commençant par v pour les variables.

  2. Un nom comme vrtfDoc2 signifie généralement: cette variable contient une RTF (et nécessite généralement le xxx: function ensemble de nœuds() à appliquer à elle pour produire un arbre ordinaire de celui-ci). Cependant, ce n'est pas le cas dans votre cas.

Par conséquent, un nom de paramètre tel que: pDoc2 est plus précis et informatif.

Questions connexes