2017-06-29 178 views
0

移动匹配的行的其余节点我有以下输入XML:分组和使用XSLT 1.0

<?xml version="1.0" encoding="UTF-8"?> 
<response> 
    <case> 
     <CMEDIA>Phone</CMEDIA> 
    </case> 
    <results> 
     <row> 
     <IKEY>TestKey1</IKEY> 
     <OBJECTID>TestObject1</OBJECTID> 
     <OBJECTPHYFILEID>ObjPhyField1</OBJECTPHYFILEID> 
     </row> 
     <row> 
     <IKEY>TestKey1</IKEY> 
     <OBJECTID>TestObject2</OBJECTID> 
     <OBJECTPHYFILEID>ObjPhyField2</OBJECTPHYFILEID> 
     </row> 
     <row> 
     <IKEY>TestKey1</IKEY> 
     <OBJECTID>TestObject3</OBJECTID> 
     <OBJECTPHYFILEID>ObjPhyField3</OBJECTPHYFILEID> 
     </row> 
     <row> 
     <IKEY>TestKey4</IKEY> 
     <OBJECTID>TestObject4</OBJECTID> 
     <OBJECTPHYFILEID>ObjPhyField4</OBJECTPHYFILEID> 
     </row> 
    </results> 
</response> 

我的要求是将所有的匹配<IKEY>行&一个<row>下拖曳移动并移动<OBJECTID> & <OBJECTPHYFILEID>节点存在于匹配的<IKEY>行(即在同一行中)在该新节点<SourceInstance>下。最后,我的输出XML应该如下:

<?xml version="1.0" encoding="UTF-8"?> 
<response> 
    <case> 
     <CMEDIA>Phone</CMEDIA> 
    </case> 
    <results> 
     <row> 
     <IKEY>TestKey1</IKEY> 
     <Sources> 
      <SourceInstance> 
       <OBJECTID>TestObject1</OBJECTID> 
       <OBJECTPHYFILEID>ObjPhyField1</OBJECTPHYFILEID> 
      </SourceInstance> 
      <SourceInstance> 
       <OBJECTID>TestObject2</OBJECTID> 
       <OBJECTPHYFILEID>ObjPhyField2</OBJECTPHYFILEID> 
      </SourceInstance> 
      <SourceInstance> 
       <OBJECTID>TestObject3</OBJECTID> 
       <OBJECTPHYFILEID>ObjPhyField3</OBJECTPHYFILEID> 
      </SourceInstance> 
     </Sources> 
     </row> 
     <row> 
     <IKEY>TestKey4</IKEY> 
     <Sources> 
      <SourceInstance> 
       <OBJECTID>TestObject4</OBJECTID> 
       <OBJECTPHYFILEID>ObjPhyField4</OBJECTPHYFILEID> 
      </SourceInstance> 
     </Sources> 
     </row> 
    </results> 
</response> 

我用下面的XSLT尝试,但未能达到预期的xml:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:key name="ikey" match="row" use="string(IKEY)" /> 
    <xsl:template match="results"> 
     <xsl:copy> 
     <xsl:apply-templates select="row[generate-id() = generate-id(key('ikey', string(IKEY))[1])]" mode="ikey" /> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="row" mode="ikey"> 
     <xsl:choose> 
     <xsl:when test="IKEY"> 
      <row> 
       <IKEY> 
        <xsl:value-of select="//IKEY" /> 
       </IKEY> 
       <Sources> 
        <xsl:for-each select="OBJECTID"> 
        <SourceInstance> 
         <xsl:value-of select="//key('ikey', IKEY)/OBJECTID" /> 
        </SourceInstance> 
        </xsl:for-each> 
       </Sources> 
      </row> 
     </xsl:when> 
     </xsl:choose> 
    </xsl:template> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

我相信,我在这里失去了一些东西。有人可以帮我吗?

+0

哪里' ObjPhyField3'数据从何而来? –

+0

@马丁Honnen,我很抱歉没有添加正确的输入xml的问题。我现在添加了它。你现在可以看到' ObjPhyField3'。 –

回答

1

使用key()功能,你可以找到当前组中的所有内容,然后可以将它们作为需要:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:key name="ikey" match="row" use="string(IKEY)" /> 

    <xsl:template match="results"> 
     <xsl:copy> 
      <xsl:apply-templates select="row[generate-id() = generate-id(key('ikey', string(IKEY))[1])]" mode="ikey" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="row" mode="ikey"> 
     <xsl:choose> 
      <xsl:when test="IKEY"> 
       <row> 
        <xsl:copy-of select="IKEY"/> 
        <Sources> 
         <xsl:apply-templates select="key('ikey', IKEY)"/> 
        </Sources> 
       </row> 
      </xsl:when> 
     </xsl:choose> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="row"> 
     <SourceInstance> 
      <xsl:apply-templates select="*[not(self::IKEY)]"/> 
     </SourceInstance> 
    </xsl:template> 

</xsl:stylesheet> 
+0

感谢您的回复。如何通过指定类似''''等的节点来获取数据?提出这个问题的原因是我只需要很少的节点。 –

+0

我懂了!类似下面,我应该尝试:'的 \t \t ' –

+0

非常感谢您的支持。加一个给你。 –