2012-05-01 53 views
1

我正試圖解決的一個當前問題是通過xslt生成兩個具有差異和相似性的xml文件的比較。將xml片段傳遞給xslt作爲參數

例如,第一xml文件看起來像

<?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> 

第二文件看起來像

<?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> 

當我嵌入第二文件到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"> 
    <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> 

使用以下c#代碼時:

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(); 
     } 

當我從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> 

改變C#的方法去除嵌入XML來

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(); 
     } 

我從變換空白輸出,支持我,我的生活不明白爲什麼。我使用調試器通過兩個版本加強和參數值看起來都occassions相同,但是當參數傳遞版本打下面的代碼片段在XSLT轉換不會發生:

<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> 

任何幫助或建議將是多少appeciated。

回答

4

的問題是在此代碼

<xsl:param name="vrtfDoc2" />  

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

此分析包含XSLT樣式表文件,定位格洛巴; xsl:param具有name屬性的字符串值"vrtfDoc2"並選擇此xsl:param的子元素 - 但它沒有子節點,因此$vDoc2的值爲空節點集。

解決方案

使用只是

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

注意事項命名

爲現在的名稱是混亂和誤導請重命名參數:

  1. 對於變量,使用以p開頭的名稱,參數和名稱以v開頭。

  2. vrtfDoc2的名稱通常意味着:這個變量包含RTF(和通常需要的XXX:節點集()函數,以便從它產生規則樹被應用於它)。但是,你的情況並非如此。

因此,像pDoc2這樣的參數名稱更加精確和翔實。