-1

我需要合并两个节点街道,因为它们具有相同的:

  • 父节点:city NEW YORK
  • 方法相同:修改
  • 相同的ID:0

必须合并属性值(请参阅本文末尾的输出文件)

这是输入文件:

<country>
<state id="NEW JERSEY">
    <city id="NEW YORK">
     <district id="BRONX" method="modify">

        <street id="0" method="modify">
           <attributes>
              <temperature>98</temperature>
              <altitude>1300</altitude>
           </attributes>
        </street>

        <dadada id="99" method="modify" />

        <street id="0" method="modify">
           <attributes>
              <temperature>80</temperature>
              <streetnumber> 67 </streetnumber>
           </attributes>
        </street>

        <dididi id="432" method="modify" />

     </district>


  </city>

</state>

预期输出:

<country>
<state id="NEW JERSEY">
    <city id="NEW YORK">
     <district id="BRONX" method="modify">

        <street id="0" method="modify">
           <attributes>
              <temperature>80</temperature>
              <altitude>1300</altitude>
              <streetnumber> 67 </streetnumber>
           </attributes>
        </street>

        <dadada id="99" method="modify" />

        <dididi id="432" method="modify" />

     </district>

  </city>

</state>
</country>

请帮忙,我刚刚开始 XSLT

4

1 回答 1

1

我假设您对 XSLT 2.0 感兴趣,因为这就是您标记问题的方式。如果您需要等效的 XSLT 1.0,请告诉我。这个 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:strip-space elements="*" />

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

<xsl:template match="*[street]">
  <xsl:copy>
   <xsl:apply-templates select="@*"/>
   <xsl:for-each-group select="street" group-by="@method">
    <xsl:apply-templates select="current-group()[1]" />
   </xsl:for-each-group>
   <xsl:apply-templates select="node()[not(self::street)]"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="street/attributes">
 <xsl:copy>
  <xsl:apply-templates select="@*"/>
   <xsl:variable name="grouped-method" select="../@method" />  
   <xsl:for-each-group select="../../street[@method=$grouped-method]/attributes/*" group-by="name()">
    <xsl:apply-templates select="current-group()[1]" />
   </xsl:for-each-group>    
  <xsl:apply-templates select="comment()|processing-instruction()"/>
 </xsl:copy>
</xsl:template>

</xsl:stylesheet> 

解释

第二个模板,匹配作为街道父元素的元素,将通过常用方法对子街道进行分组。对于每个组,仅复制组中的第一条街道。其余的被丢弃。

当该组的第一条街道在第三个模板中具有其“属性”节点处理时,我们合并来自同一组的所有属性。'attributes' 可能是 XML 文档中不幸的元素名称!通过查看具有相同街道父级(布朗克斯区)的所有联合街道的所有“属性”子节点并按元素名称分组来实现此分组。如果这样的组中有多个元素,则只需从第一个元素中获取值。

我不确定这是否正是您想要的,因为尽管街道属性由“父亲”节点(布朗克斯)合并,但它们并未在城市级别合并。这反映了您的问题的模棱两可。样本日期中街道的“父”节点是地区而不是城市。如果我弄错了,并且您想在城市级别进行分组,请澄清并更新您的问题。

于 2012-07-11T09:35:39.867 回答