每个匹配元素的

时间:2016-05-31 14:51:01

标签: xml xslt xpath

所以这是我的输入XML:

    <?xml version="1.0" encoding="utf-8"?>
    <modifs>
  <modif id="229818">
<avant num_words="1">dans</avant>
<apres num_words="1">par</apres></modif>
  <modif id="196216">
<avant num_words="1">dans</avant>
<apres num_words="1">parmi</apres></modif>
  <modif id="2162">
<avant num_words="1">dans</avant>
<apres num_words="1">pour</apres></modif>
  <modif id="9273">
<avant num_words="1">dans</avant>
<apres num_words="1">pour</apres></modif>
</modifs>

基本上我想要做的是复制所有内容,但重复内容除外。对于所述重复内容,我想将不同的ID分组在同一类型的第一个元素下。我想得到的结果是这样的:

 <?xml version="1.0" encoding="utf-8"?>
    <modifs>
  <modif id="229818">
<avant num_words="1">dans</avant>
<apres num_words="1">par</apres></modif>
  <modif id="196216">
<avant num_words="1">dans</avant>
<apres num_words="1">parmi</apres></modif>
  <modif id="2162">
<extra_id="9273">
<avant num_words="1">dans</avant>
<apres num_words="1">pour</apres></modif>
</modifs>

这是我到目前为止的尝试:我试图首先检查是否已经有重复(如果是,什么都不做),然后如果之后有重复。如果有,请获取其id属性并复制它。 (这就是我不知道该怎么做)。最后,如果没有重复项,只需复制元素。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>

  <xsl:template match="modifs">
    <xsl:for-each select="./modif">
      <xsl:choose>
        <xsl:when test="./avant=preceding-sibling::modif/avant">
          <xsl:if test="./apres=preceding-sibling::modif/apres">
          </xsl:if>
        </xsl:when>
        <xsl:when test="./avant=following-sibling::modif/avant">
          <xsl:if test="./apres=following-sibling::modif/apres">
            <xsl:element name="modif">
            <xsl:for-each select="following-sibling::modif/@id=./@id">
              <xsl:value-of select="."/>            
          </xsl:for-each>
              <xsl:copy-of select="."/>
              </xsl:element>
          </xsl:if>
        </xsl:when>
        <xsl:otherwise>
          <xsl:copy-of select="."/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet> 

我不知道我的问题是否清楚,如果没有,或者是否有任何其他问题(或我的英语),请告诉我,我会很乐意改变它。

由于

1 个答案:

答案 0 :(得分:1)

您可以尝试Muenchian grouping

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

        <xsl:key name="kmodif" match="modif" use="concat(avant, '|', apres)"/>

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

        <xsl:template match="/modifs">
            <xsl:copy>
                <xsl:for-each
                    select="modif[generate-id() = generate-id(key('kmodif', concat(avant, '|', apres))[1])]" >
                    <!-- group -->
                    <xsl:copy>
                        <xsl:apply-templates select="@*" />

                        <xsl:for-each
                            select="key('kmodif', concat(avant, '|', apres))[position() != 1]" >
                            <!-- group member-->
                            <extra id="{@id}" />
                        </xsl:for-each>
                        <xsl:apply-templates select="*" />
                    </xsl:copy>
                    </xsl:for-each>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>

使用以下输出:

        <modifs>
            <modif id="229818">
                <avant num_words="1">dans</avant>
                <apres num_words="1">par</apres>
            </modif>
            <modif id="196216">
                <avant num_words="1">dans</avant>
                <apres num_words="1">parmi</apres>
            </modif>
            <modif id="2162">
                <extra id="9273"/>
                <avant num_words="1">dans</avant>
                <apres num_words="1">pour</apres>
            </modif>
        </modifs>