2012-05-01 2 views
1

현재 해결해야 할 문제는 xslt를 통해 차이점과 유사점이있는 두 xml 파일의 비교를 생성하는 것입니다. 예상대로 I 출력 작품 파일 XSLT에 두번째 파일을 포함하는 경우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> 

보이는 것처럼

예를 들어 첫 번째 XML 파일 같습니다

<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# 코드를 사용하는 경우 :

나는 내 인생 I, 나는이 변환에서 빈 출력을 얻을

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

에 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); 

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

      t.Transform(xmlReader, null, 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

문제는이 코드에 : 이것은, XSLT 스타일 시트를 포함하는 파일을 구문 분석 globa의 위치를 ​​

<xsl:param name="vrtfDoc2" />  

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

; xsl:param이 이고 문자열 값이 "vrtfDoc2"이고이 xsl:param의 하위 요소를 선택합니다. 그러나 자식은 없으므로 $vDoc2 값은 빈 노드 집합입니다.

솔루션 :

사용 단지 :

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

노트 이름 지정에 대한 : 현재의 이름은 혼란과 오해로

매개 변수의 이름을 변경하십시오

  1. 변수의 경우 v으로 시작하는 매개 변수 및 이름의 경우 p으로 시작하는 이름을 사용하십시오. 이 변수는 RTF 포함 (보통 XXX 필요 : 노드 집합() 함수는로부터 정기적 트리를 생성하기 위해 적용된 것으로)

  2. vrtfDoc2 같은 이름은 일반적 의미. 그러나 귀하의 경우에는 그렇지 않습니다.

따라서, 같은 매개 변수 이름 : pDoc2이 더 정확하고 유익한 정보입니다.