需要基于公共密钥在xslt中合并2 xml

时间:2016-11-21 08:41:02

标签: xslt

我有2个源变量需要根据XSLT中的公共密钥进行合并

变量1 :我为每位员工添加了一些属性。

<EmpDetails>
<Emp>
<ID>1</ID>
<Name>A</Name>
<Address>abc 123</Address>
<Contact>1234567890</Contact>
<DOB>01/01/1989</DOB>
<Emp>
<Emp>
  <ID>2</ID>
   <Name>B</Name>
   <Address>ASDF</Address>
   <Contact>123456</Contact>
   <DOB>02/02/1990</DOB>
   <Emp>
   </EmpDetails>

变量2:

<EmpAgeDetails>
<EmpAge>
   <ID>1</ID>
   <Age>27</Age>
  <EmpAge>
  <EmpAge>
    <ID>2</ID>
   <Age>26</Age>
  <EmpAge>
 </EmpAgeDetails>

预期产出:

 <EmpDetails>
 <Emp>
   <ID>1</ID>
   <Name>A</Name>
   <Address>abc 123</Address>
   <Contact>1234567890</Contact>
   <DOB>01/01/1989</DOB>
   <Age>27</Age>
  <Emp>
  <Emp>
      <ID>2</ID>
      <Name>B</Name>
      <Address>ASDF</Address>
      <Contact>123456</Contact>
      <DOB>02/02/1990</DOB>
      <Age>26</Age>
     <Emp>
      </EmpDetails>

我正在使用模板复制变量1中的所有元素,这些元素工作正常。 但现在我需要合并Age的额外元素。 任何帮助表示赞赏

1 个答案:

答案 0 :(得分:0)

使用XSLT 3.0和xsl:merge,如最新的Altova XMLSpy / Raptor或Saxon 9.7 EE所支持,您可以使用

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:math="http://www.w3.org/2005/xpath-functions/math" xmlns:array="http://www.w3.org/2005/xpath-functions/array" xmlns:map="http://www.w3.org/2005/xpath-functions/map" exclude-result-prefixes="array fn map math xs">

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:param name="doc1">
        <EmpDetails>
            <Emp>
                <ID>1</ID>
                <Name>A</Name>
                <Address>abc 123</Address>
                <Contact>1234567890</Contact>
                <DOB>01/01/1989</DOB>
            </Emp>
            <Emp>
                <ID>2</ID>
                <Name>B</Name>
                <Address>ASDF</Address>
                <Contact>123456</Contact>
                <DOB>02/02/1990</DOB>
            </Emp>
        </EmpDetails>
    </xsl:param>

    <xsl:param name="doc2">
        <EmpAgeDetails>
            <EmpAge>
                <ID>1</ID>
                <Age>27</Age>
            </EmpAge>
            <EmpAge>
                <ID>2</ID>
                <Age>26</Age>
            </EmpAge>
        </EmpAgeDetails>
    </xsl:param>

    <xsl:template match="/" name="xsl:initial-template">
        <EmpDetails>
            <xsl:merge>
                <xsl:merge-source select="$doc1/EmpDetails/Emp">
                    <xsl:merge-key select="ID"></xsl:merge-key>
                </xsl:merge-source>
                <xsl:merge-source select="$doc2/EmpAgeDetails/EmpAge">
                    <xsl:merge-key select="ID"></xsl:merge-key>
                </xsl:merge-source>
                <xsl:merge-action>
                    <xsl:copy>
                        <xsl:apply-templates select="current-merge-group()[1]/*, fn:current-merge-group()[2]/Age"/>
                    </xsl:copy>
                </xsl:merge-action>
            </xsl:merge>        
        </EmpDetails>

    </xsl:template>

</xsl:stylesheet>

使用XSLT 2.0,你可以分组:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

    <xsl:param name="doc1">
        <EmpDetails>
            <Emp>
                <ID>1</ID>
                <Name>A</Name>
                <Address>abc 123</Address>
                <Contact>1234567890</Contact>
                <DOB>01/01/1989</DOB>
            </Emp>
            <Emp>
                <ID>2</ID>
                <Name>B</Name>
                <Address>ASDF</Address>
                <Contact>123456</Contact>
                <DOB>02/02/1990</DOB>
            </Emp>
        </EmpDetails>
    </xsl:param>

    <xsl:param name="doc2">
        <EmpAgeDetails>
            <EmpAge>
                <ID>1</ID>
                <Age>27</Age>
            </EmpAge>
            <EmpAge>
                <ID>2</ID>
                <Age>26</Age>
            </EmpAge>
        </EmpAgeDetails>
    </xsl:param>

    <xsl:template match="/" name="main">
        <EmpDetails>
            <xsl:for-each-group select="$doc1/EmpDetails/Emp, $doc2/EmpAgeDetails/EmpAge" group-by="ID">
                <xsl:copy>
                    <xsl:copy-of select="current-group()[1]/*, current-group()[2]/Age"/>
                </xsl:copy>
            </xsl:for-each-group>        
        </EmpDetails>
    </xsl:template>

</xsl:stylesheet>
相关问题