如果父节点值匹配,则合并第一个父节点下各自父节点的所有子节点 [英] Merge all child nodes of respective parent under first parent, if parent node value matches

查看:36
本文介绍了如果父节点值匹配,则合并第一个父节点下各自父节点的所有子节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的输入是这样的.

<?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:

I tried following 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>

它给了我如下输出,虽然它能够对具有相同损伤代码的子元素进行分组,但没有给出所需的输出,它没有复制部件位置下的所有标签,只有 seqNumber 在输出中可见.也非常感谢任何帮助.感谢大家的帮助.

and it is giving me ouput like below, Though it is able to group child elements having same DamageCode, but not giving the desired ouput, it is not copying all tags under part position, only seqNumber is visible in output . Also Any help is much appreciated. Thanks for all the help.

<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>

推荐答案

您的 XSLT 中有一个忽略 PartPosition

You have a template in your XSLT that ignores PartPosition

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

因此,当您在 copy 模板中执行 时,因为您位于 DamagePosition> 此时,上面的模板将匹配子 PartPosition 并忽略它.

Therefore, when you do <xsl:apply-templates/> in your copy template, because you are positioned on a DamagePosition at this point, the above template will match the child PartPosition and simply ignore it.

也许此时您应该忽略 DamageSeqNumber 而不是 PartPosition?

Perhaps you should be ignoring DamageSeqNumber instead of PartPosition at this point?

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

Also, you probably don't really need the copy template at all. Instead, change the call to it, to simply get all the child elements of the key, and then let the identity template take care of it.

<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 元素,尽管您的输入中只有一个.

This doesn't quite give the output you show in your question, because you show two OperationPosition elements in your output, although there is only one in your input.

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

If you wanted OperationPosition elements before PartPosition elements, you could replace the existing <xsl:apply-templates select="key('kuserID',DamageCode)/*" /> with these two lines instead:

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

这篇关于如果父节点值匹配,则合并第一个父节点下各自父节点的所有子节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆