2016-09-28 8 views
0

私はxsltを使用して以下の2つのxmlをマージします。XSLT -cを使用した複数のXMLマージ#

   XmlWriterSettings settings = new XmlWriterSettings(); 
       settings.OmitXmlDeclaration = true; 
       settings.ConformanceLevel = ConformanceLevel.Fragment; 
       settings.CloseOutput = false; 
       XElement root = new XElement("root", 
       XElement.Load("C:\\first.xml"), 
       XElement.Load("C:\\second.xml")); 

         XDocument newTree = new XDocument(); 

         using (XmlWriter writer = XmlWriter.Create(newTree.CreateWriter(), settings)) 
       { 
        XslCompiledTransform xslt = new XslCompiledTransform(); 

        xslt.Load(@"..\..\XSDParser.xslt"); 

       xslt.Transform(root.CreateReader(), writer); 
       newTree.Save("result.xml"); 
       writer.Close(); 
       } 

ルートは、以下のXMLを

<root> 
    <Promotions> 
    <Promotion> 
     <Category>Arts &amp; Entertainment</Category> 
     <Client>Client1</Client> 
     <Title>Get your Free 2</Title> 
    </Promotion> 
    <Promotion> 
     <Category>Arts &amp; Entertainment</Category> 
     <Client>Client1</Client> 
     <Title>Get your Free 4</Title> 
    </Promotion> 
    <Promotion> 
     <Category>Arts &amp; Entertainment</Category> 
     <Client>client1</Client> 
     <Title>Get your Free 5</Title> 
    </Promotion> 
    <Promotion> 
     <Category>Community &amp; Neighborhood</Category> 
     <Client>Client2</Client> 
     <Title>Get your Free 1</Title> 
    </Promotion> 
    <Promotion> 
     <Category>Education</Category> 
     <Client>Client3</Client> 
     <Title>Get Your Free 3</Title> 
    </Promotion> 
    </Promotions> 
    <Promotions> 
    <Promotion> 
     <Category>Arts &amp; Entertainment</Category> 
     <Client>Client11111</Client> 
     <Title>Get your Free 2</Title> 
    </Promotion> 
    <Promotion> 
     <Category>Arts &amp; Entertainment</Category> 
     <Client>Client1</Client> 
     <Title>Get your Free 4</Title> 
    </Promotion> 
    <Promotion> 
     <Category>Arts &amp; Entertainment</Category> 
     <Client>client1</Client> 
     <Title>Get your Free 5</Title> 
    </Promotion> 
    <Promotion> 
     <Category>Community &amp; Neighborhood</Category> 
     <Client>Client2</Client> 
     <Title>Get your Free 1</Title> 
    </Promotion> 
    <Promotion> 
     <Category>Education</Category> 
     <Client>Client3</Client> 
     <Title>Get Your Free 3</Title> 
    </Promotion> 
    </Promotions> 
</root> 

を含み、XSLT以下

<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'> 
     <xsl:output method='xml' /> 
     <xsl:key name='categories' match='Category' use='.' /> 
     <xsl:template match='/'> 
     <xsl:for-each select="/Promotions/Promotion/Category[ 
      generate-id(.) = generate-id(key('categories', .)[1]) 
      ]"> 
      <xsl:variable name='cname' select='.' /> 
      <Category title='{.}'> 
      <xsl:for-each select='/Promotions/Promotion[Category=$cname]'> 
       <Title> 
       <xsl:value-of select='Title' /> 
       </Title> 
      </xsl:for-each> 
      </Category> 
     </xsl:for-each> 
     </xsl:template> 
    </xsl:stylesheet> 

しかしnewTree.Save( "result.xml")を使用します。 エラー

追加情報を返します:無効なXML文書で 結果が希望の状態文書にトークンEndDocumentのを。

どこが間違っていますか?誰かがこれについてヒントを提供することはできますか?あなたは持っている最初の問題は、あなたがツリーを保存する前にwriterを閉じなければならないということである

答えて

1

....また、あなたのXSLTでXPathにroot要素を占めていない

xslt.Transform(root.CreateReader(), writer); 
writer.Close(); 
newTree.Save("result.xml"); 

、意味xsl:for-eachは何も選択しないので、何も出力しません。

<xsl:for-each select='key("categories", .)/..'> 

それはもう少しエレガントかもしれません:だから、両方のケースでは、xsl:for-each

<xsl:for-each select="/root/Promotions/Promotion.... 

実際には、インナーxsl:for-eachに、あなたが実際にキーを使用することができます....このようにする必要がありますあなたがCategoryに基づいてPromotionに一致するようにキーを変更した場合。

このXSLTを試してください(注:1つのルート要素を出力するように変更しました)。

<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'> 
    <xsl:output method='xml' /> 

    <xsl:key name='promotions' match='Promotion' use='Category' /> 

    <xsl:template match='/'> 
    <Root> 
     <xsl:for-each select="/root/Promotions/Promotion[ 
      generate-id(.) = generate-id(key('promotions', Category)[1]) 
      ]"> 
      <xsl:variable name='cname' select='Category' /> 
      <Category title='{$cname}'> 
      <xsl:for-each select="key('promotions', Category)"> 
       <Title> 
       <xsl:value-of select='Title' /> 
       </Title> 
      </xsl:for-each> 
      </Category> 
     </xsl:for-each> 
    </Root> 
    </xsl:template> 
</xsl:stylesheet> 
関連する問題