如果父节点值匹配,则合并第一个父节点下相应父节点的所有子节点

时间:2015-07-16 21:50:54

标签: xml xslt

Hi My Input就是这样。

<?xml version="1.0" encoding="UTF-8"?>
         <Claim>
            <Mileage>9837</Mileage>
            <DamagePosition>
               <DamageSeqNumber>3</DamageSeqNumber>
               <DamageCode>2727004</DamageCode>
               <PartPosition>
                  <SeqNumber>1</SeqNumber>
                  <PartNumber>A2035400253</PartNumber>
               </PartPosition>
            </DamagePosition>
            <DamagePosition>
               <DamageSeqNumber>1</DamageSeqNumber>
               <DamageCode>2727004</DamageCode>
               <PartPosition>
                  <SeqNumber>3</SeqNumber>
                  <PartNumber>A1409910055</PartNumber>
               </PartPosition>
            </DamagePosition>
            <DamagePosition>
               <DamageSeqNumber>8</DamageSeqNumber>
               <DamageCode>2727004</DamageCode>
               <OperationPosition>
                  <SeqNumber>8</SeqNumber>
                  <Opcode>02-2710-01</Opcode>
               </OperationPosition>
            </DamagePosition>
            <DamagePosition>
               <DamageSeqNumber>4</DamageSeqNumber>
               <DamageCode>3221136</DamageCode>
               <PartPosition>
                  <SeqNumber>4</SeqNumber>
                  <PartNumber>A2033202889</PartNumber>
               </PartPosition>
            </DamagePosition>
         </Claim>  

并且所需的输出是:

<?xml version="1.0" encoding="UTF-8"?>
         <Claim>
            <Mileage>9837</Mileage>
            <DamagePosition>
               <DamageSeqNumber>3</DamageSeqNumber>
               <DamageCode>2727004</DamageCode>
               <OperationPosition>
                  <SeqNumber>8</SeqNumber>
                  <Opcode>02-2710-01</Opcode>
               </OperationPosition>
               <PartPosition>
                  <SeqNumber>1</SeqNumber>
                  <PartNumber>A2035400253</PartNumber>
               </PartPosition>
               <PartPosition>
                  <SeqNumber>3</SeqNumber>
                  <PartNumber>A1409910055</PartNumber>
               </PartPosition>
               <OperationPosition>
                  <SeqNumber>8</SeqNumber>
                  <Opcode>02-2710-01</Opcode>
               </OperationPosition>
            </DamagePosition>
            <DamagePosition>
               <DamageSeqNumber>4</DamageSeqNumber>
               <DamageCode>3221136</DamageCode>
               <PartPosition>
                  <SeqNumber>4</SeqNumber>
                  <PartNumber>A2033202889</PartNumber>
               </PartPosition>
            </DamagePosition>
         </Claim>

我试过跟随xslt:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:key name="kuserID" match="DamagePosition"  use="DamageCode"/>
 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*">
         <xsl:sort select="DamageCode" data-type="number"/>
       </xsl:apply-templates>
     </xsl:copy>
 </xsl:template>
 <xsl:template match=
 "DamagePosition|DamageCode
 |PartPosition"/>
 <xsl:template match=
  "DamagePosition
    [generate-id()
    =
     generate-id(key('kuserID', DamageCode)[1])
     ]">
  <DamagePosition>
   <xsl:copy-of select="DamageCode"/>
   <xsl:apply-templates mode="copy" select="key('kuserID',DamageCode)" />
  </DamagePosition>
 </xsl:template>
 <xsl:template match="DamagePosition" mode="copy">
  <PartPosition>
   <xsl:apply-templates/>
  </PartPosition>
 </xsl:template>
</xsl:stylesheet>

它给我的输出如下,虽然它能够对具有相同DamageCode的子元素进行分组,但是没有给出所需的输出,但它不会复制部分位置下的所有标签,只有seqNumber在输出中可见。此外,任何帮助非常感谢。感谢您的帮助。

<Claim>
   <Mileage>9837</Mileage>
   <DamagePosition>
      <DamageCode>2727004</DamageCode>
      <PartPosition>
         <DamageSeqNumber>3</DamageSeqNumber>
      </PartPosition>
      <PartPosition>
         <DamageSeqNumber>1</DamageSeqNumber>
      </PartPosition>
      <PartPosition>
         <DamageSeqNumber>8</DamageSeqNumber>
         <OperationPosition>
            <SeqNumber>8</SeqNumber>
            <Opcode>02-2710-01</Opcode>
         </OperationPosition>
      </PartPosition>
   </DamagePosition>
   <DamagePosition>
      <DamageCode>3221136</DamageCode>
      <PartPosition>
         <DamageSeqNumber>4</DamageSeqNumber>
      </PartPosition>
   </DamagePosition>
</Claim>

1 个答案:

答案 0 :(得分:0)

您的XSLT中有一个忽略PartPosition

的模板
<xsl:template match="DamagePosition|DamageCode|PartPosition"/>

因此,当您在<xsl:apply-templates/>模板中执行copy时,由于此时您位于DamagePosition,上述模板将与子PartPosition匹配,简单地忽略它。

或许你现在应该忽略DamageSeqNumber而不是PartPosition

此外,您可能根本不需要copy模板。相反,更改对它的调用,只需获取键的所有子元素,然后让身份模板处理它。

<xsl:apply-templates select="key('kuserID',DamageCode)/*" />

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:key name="kuserID" match="DamagePosition"  use="DamageCode"/>

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

 <xsl:template match="DamagePosition|DamageCode|DamageSeqNumber"/>

 <xsl:template match="DamagePosition[generate-id() = generate-id(key('kuserID', DamageCode)[1])]">
  <DamagePosition>
   <xsl:copy-of select="DamageCode"/>
   <xsl:copy-of select="DamageSeqNumber"/>
   <xsl:apply-templates select="key('kuserID',DamageCode)/*" />
  </DamagePosition>
 </xsl:template>
</xsl:stylesheet>

这并不能完全显示您在问题中显示的输出,因为您在输出中显示了两个OperationPosition元素,尽管输入中只有一个。

编辑:如果您想要OperationPosition元素之前的PartPosition元素,则可以用这两行代替现有的<xsl:apply-templates select="key('kuserID',DamageCode)/*" />

<xsl:apply-templates select="key('kuserID',DamageCode)/OperationPosition" />
<xsl:apply-templates select="key('kuserID',DamageCode)/*[not(self::OperationPosition)]" />