Xml XSLT合并具有相同标识符元素的节点

Xml XSLT合并具有相同标识符元素的节点,xml,xslt,join,merge,Xml,Xslt,Join,Merge,在下面的示例中,需要通过移动子元素(如果需要)来合并元素(由元素标识),这意味着:如果xml中有2个元素,则通过将从第二个元素移动到第一个来连接它们,并移除第二个元素;否则就让它保持原样 输入XML示例: <SearchReply_OutputVariable> <part name="parameters"> <searchResponse> <userSearchRecords> <userAcco

在下面的示例中,需要通过移动
子元素(如果需要)来合并
元素(由
元素标识),这意味着:如果xml中有2个
元素,则通过将
从第二个
元素移动到第一个来连接它们,并移除第二个
元素;否则就让它保持原样

输入XML示例:

<SearchReply_OutputVariable>
  <part name="parameters">
    <searchResponse>
      <userSearchRecords>
        <userAccount>
          <login>A</login>
          <otherAttributes>
            <name>X</name>
            <value>1</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
      <userSearchRecords>
        <userAccount>
          <login>B</login>
          <otherAttributes>
            <name>X</name>
            <value>2</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
      <userSearchRecords>
        <userAccount>
          <login>C</login>
          <otherAttributes>
            <name>X</name>
            <value>1</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
      <userSearchRecords>
        <userAccount>
          <login>D</login>
          <otherAttributes>
            <name>X</name>
            <value>1</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
      <userSearchRecords>
        <userAccount>
          <login>G</login>
          <otherAttributes>
            <name>Y</name>
            <value>5</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
      <userSearchRecords>
        <userAccount>
          <login>C</login>
          <otherAttributes>
            <name>Y</name>
            <value>6</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
      <userSearchRecords>
        <userAccount>
          <login>H</login>
          <otherAttributes>
            <name>Y</name>
            <value>7</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
      <userSearchRecords>
        <userAccount>
          <login>A</login>
          <otherAttributes>
            <name>Y</name>
            <value>7</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
    </searchResponse>
  </part>
</SearchReply_OutputVariable>

A.
X
1.
B
X
2.
C
X
1.
D
X
1.
G
Y
5.
C
Y
6.
H
Y
7.
A.
Y
7.
预期输出XML:

<SearchReply_OutputVariable>
  <part name="parameters">
    <searchResponse>
      <userSearchRecords>
        <userAccount>
          <login>A</login>
          <otherAttributes>
            <name>X</name>
            <value>1</value>
          </otherAttributes>
          <otherAttributes>
            <name>Y</name>
            <value>7</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
      <userSearchRecords>
        <userAccount>
          <login>B</login>
          <otherAttributes>
            <name>X</name>
            <value>2</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
      <userSearchRecords>
        <userAccount>
          <login>C</login>
          <otherAttributes>
            <name>X</name>
            <value>1</value>
          </otherAttributes>
          <otherAttributes>
            <name>Y</name>
            <value>6</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
      <userSearchRecords>
        <userAccount>
          <login>D</login>
          <otherAttributes>
            <name>X</name>
            <value>1</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
      <userSearchRecords>
        <userAccount>
          <login>G</login>
          <otherAttributes>
            <name>Y</name>
            <value>5</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
      <userSearchRecords>
        <userAccount>
          <login>H</login>
          <otherAttributes>
            <name>Y</name>
            <value>7</value>
          </otherAttributes>
        </userAccount>
      </userSearchRecords>
    </searchResponse>
  </part>
</SearchReply_OutputVariable>

A.
X
1.
Y
7.
B
X
2.
C
X
1.
Y
6.
D
X
1.
G
Y
5.
H
Y
7.
在输出XML中现在有6个
,而在输入XML中有8个。在输入XML中有2个
值为A的
,以及2个
值为C的
。在输出XML中,这些元素被合并(
子元素从匹配的登录对中移动,而
元素从匹配的登录对中移除)

有人能给我指出正确的方向,如何解决这个问题


谢谢

谢谢Martin,我查找了与xsl相关的“分组”,这是我作为解决方案想到的:

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

  <xsl:key name="group" match="userSearchRecords" use="userAccount/login"/>

 <xsl:template match="searchResponse">
    <searchResponse>
       <xsl:for-each select="userSearchRecords[count(. | key('group', userAccount/login)[1]) = 1]">
        <xsl:sort select="userAccount/login" />
        <userSearchRecords>
            <userAccount>
                <xsl:for-each select="key('group', userAccount/login)">
                    <xsl:if test="not(preceding-sibling::userSearchRecords[userAccount/login = current()/userAccount/login])">
                        <xsl:copy-of select="userAccount/login"/>
                    </xsl:if>               
                    <xsl:copy-of select="userAccount/otherAttributes"/>
                </xsl:for-each>
            </userAccount>
        </userSearchRecords>
    </xsl:for-each>
    </searchResponse>
  </xsl:template>
</xsl:stylesheet>

谢谢Martin,我查找了与xsl相关的“分组”,这就是我提出的解决方案:

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

  <xsl:key name="group" match="userSearchRecords" use="userAccount/login"/>

 <xsl:template match="searchResponse">
    <searchResponse>
       <xsl:for-each select="userSearchRecords[count(. | key('group', userAccount/login)[1]) = 1]">
        <xsl:sort select="userAccount/login" />
        <userSearchRecords>
            <userAccount>
                <xsl:for-each select="key('group', userAccount/login)">
                    <xsl:if test="not(preceding-sibling::userSearchRecords[userAccount/login = current()/userAccount/login])">
                        <xsl:copy-of select="userAccount/login"/>
                    </xsl:if>               
                    <xsl:copy-of select="userAccount/otherAttributes"/>
                </xsl:for-each>
            </userAccount>
        </userSearchRecords>
    </xsl:for-each>
    </searchResponse>
  </xsl:template>
</xsl:stylesheet>


这是一个分组问题。在XSLT2.0中,您可以使用
,在XSLT1.0中,您可以使用带有键
的Muenchian分组。这是一个分组问题。在XSLT2.0中,您可以使用
,在XSLT1.0中,您可以使用带有键的Muenchian分组