2016-09-28 77 views
0

我有下面的代码两个合并两个xml使用xslt。多个XML合并使用XSLT -c#

   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”); 返回错误

其他信息:标记调用endDocument在状态文件将 结果无效XML文档英寸

哪里出错了?有人可以提供这个提示吗?

回答

1

你的第一个问题是,你应该保存树之前关闭writer ....

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

此外,你有没有在XPath在XSLT占root元素,意义你的xsl:for-each什么都不选,所以什么都不输出。因此,在这两种情况下,xsl:for-each应该是这样的....

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

实际上,在内部xsl:for-each,你可以实际使用的关键:

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

这可能是稍微更优雅如果您更改密钥以匹配Promotion基于Category虽然。

试试这个XSLT(注意我也改变它来输出单个根元素)。

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