2013-02-20 54 views
2

我必须将节点元素的数据从file1.xml复制到file2.xml。 file1.xml使用XSLT将数据从一个XML文档复制到另一个

<?xml version="1.0" encoding="utf-8" ?> 
<root> 
    <header> 
    <AsofDate>31-Dec-2012</AsofDate> 
    <FundName>This is Sample Fund</FundName> 
    <Description>This is test description</Description> 
    </header> 
</root> 

file2.xml

<?xml version="1.0" encoding="utf-8" ?> 
<root id="1"> 
    <header id="2"> 
    <AsofDate id="3"/> 
    <FundName id="4" /> 
    <Description id="5" /> 
    </header> 
</root> 

合并file1.xml到file2.xml后,结果应该看看下面:

<?xml version="1.0" encoding="utf-8" ?> 
<root id="1"> 
    <header id="2"> 
    <AsofDate id="3">31-Dec-2012</AsofDate> 
    <FundName id="4">This is Sample Fund</FundName> 
    <Description id="5">This is test description</Description> 
    </header> 
</root> 

我使用在XSLT下面转换文件。

<?xml version="1.0" encoding="utf-8" ?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()" /> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

下面是代码用于执行变换:

XslCompiledTransform tf = new XslCompiledTransform(); 
    tf.Load("TranFile.xsl"); 

    tf.Transform("file1.xml", "file2.xml"); 

但上面的代码重写file2的内容与内容file1.xml。这只是示例XML。在实际情况下,我们不知道XML文件的节点和层次结构的名称。但是无论哪种结构对于文件和场景都是一样的,都是完全相同的。我是XSLT新手,不确定这是否是正确的方法来完成结果。是否真的有可能通过XSLT实现结果。

+0

的可能重复的[XSLT:一个简单的方式来合并XML文件(http://stackoverflow.com/questions/1510688/xslt-a-simple-way-to-merge-xml-files) – iTech 2013-02-20 20:18:43

+0

这里我不知道来自服务的XML结构。 – Nps 2013-02-20 20:26:06

+0

我想,在真实情况下,file2.xml中的id不会是顺序的,不是?我的意思是你会发现像

...顺便说一句,你是否尝试使用文档('')函数? – 2013-02-20 22:54:11

回答

4

,我发布的解决方案是写铭记以下几点:

  • 需要合并的唯一的事情是属性。文本和元素节点在从file1.xml中出现时被复制。

  • 的@id属性不是在file2.xml依次编号所以@ ID在file2.xml可以是(例如)121 432 233 12 944,而不是1 2 3 4 5。如果情况后者则不需要file2.xml来生成所需的输出。

  • 可以使用document()函数来访问不同于当前文件的文件。如果XslCompiledTransform在使用文档功能时发生错误,我会建议遵循此using document() function in .NET XSLT generates error。我正在使用不同的XSLT处理器(xsltproc),它工作正常。

该解决方案是基于保持到外部文件的引用,因此每个我们在file1.xml基准处理的元件的时间被移动在file2.xml同一元素指向。这可以这样做,因为根据问题,这两个文件呈现相同的元素层次结构。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" indent="no"/> 

    <!-- Match the document node as an entry point for matching the files --> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="node()"> 
      <xsl:with-param name="doc-context" select="document('file2.xml')/node()" /> 
     </xsl:apply-templates> 
    </xsl:template> 

    <!-- In this template we copy the elements and text nodes from file1.xml and 
     we merge the attributes from file2.xml with the attributes in file1.xml --> 
    <xsl:template match="node()"> 
     <!-- We use this parameter to keep track of where we are in file2.xml by 
      mimicking the operations that we do in the current file. So we are at 
      the same position in both files at the same time. --> 
     <xsl:param name="doc-context" /> 

     <!-- Obtain current position in file1.xml so we know where to look in file2.xml --> 
     <xsl:variable name="position" select="position()" /> 

     <!-- Copy the element node from the current file (file1.xml) --> 
     <xsl:copy> 
      <!-- Merge attributes from file1.xml with attributes from file2.xml --> 
      <xsl:copy-of select="@*|$doc-context[position() = $position]/@*" /> 
      <!-- Copy text nodes and process children --> 
      <xsl:apply-templates select="node()"> 
       <xsl:with-param name="doc-context" select="$doc-context/node()" /> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

非常感谢,这个解决方案完美解决了这个问题。 – Nps 2013-02-21 04:42:37

+0

我想知道,如果两个xml文件都不是物理文件,我们如何实现相同的解决方案。如果这些是从数据库代码生成的。 – Nps 2013-02-21 05:01:38

+0

很高兴看到XSLT中的一些评论。 – Sepster 2016-08-16 22:45:51

相关问题