XSLT - 基于连续行上的隐式链接进行合并、排序、重复数据删除、排序和重新编号



我有一个无法修复的 XSLT 问题。

我有以下 XML 的 XML 片段:

<memberP>
<patent>
..
<patentCitations tsip:action="replace">
                 <fieldOfSearch>
                       <classificationJp tsip:action="replace">
                              <jppc tsip:rangeFrom="1">A61C-5/18</jppc>
                              <jppc tsip:rangeTo="1">A61C-5/120</jppc>
                              <jppc tsip:rangeFrom="2">A61C-8/00</jppc>
                              <jppc tsip:rangeTo="2">A61C-13/38</jppc>
                              <jppc tsip:rangeFrom="3">A61C-5/10</jppc>
                              <jppc tsip:rangeTo="3">A61C-5/12</jppc>
                              <jppc>A61C-13/39</jppc>
                              <jppc>A61C-13/40</jppc>
                              <jppc>A61C-13/39</jppc>
                       </classificationJp>
                 </fieldOfSearch> 
</patentCitations>
...
</patent>
<patent>
..
<patentCitations tsip:action="replace">
                 <fieldOfSearch>
                       <classificationJp tsip:action="replace">
                              <jppc tsip:rangeFrom="1">A61C-5/15</jppc>
                              <jppc tsip:rangeTo="1">A61C-5/16</jppc>
                              <jppc>A61C-13/39</jppc>
                              <jppc>A61C-13/40</jppc>
                              <jppc>A61C-13/39</jppc>
                       </classificationJp>
                 </fieldOfSearch>
</patentCitations>
..
</patent>
</memberP>

我需要做的是根据 tsip:rangeFrom 和 tsip:rangeTo 属性值合并、重复、排序和重新编号!

使用以下代码片段:

<xsl:key name="citedJpcc" match="memberP//patent/patentCitations/fieldOfSearch/classificationJp/jppc" use="."/>
<!-- The Wrapper-->
<xsl:template match="/">
..
..
<fieldOfSearch>    
<xsl:if test="patent/patentCitations/fieldOfSearch/classificationJp
  <classificationJp tsip:action="replace">
    <xsl:variable name="classificationJppc">  -- variable holds subtree
     <xsl:for-each select="patent/patentCitations/fieldOfSearch/classificationJp/jppc">
     <xsl:sort order="descending" select="@*"/> -- Sorts on attributes
     <xsl:if test="generate-id(.) = generate-id(key('citedJpcc', .))"> -- dedupes
     <xsl:element name="jppc">
       <xsl:if test="@tsip:rangeFrom">
        <xsl:attribute name="tsip:rangeFrom">
          <xsl:value-of select="@tsip:rangeFrom"/>
        </xsl:attribute>
       </xsl:if>
       <xsl:if test="@tsip:rangeTo">
         <xsl:attribute name="tsip:rangeTo">
           <xsl:value-of select="@tsip:rangeTo"/>
         </xsl:attribute>
       </xsl:if>
       <xsl:copy-of select="text()"/>
     </xsl:element>
   </xsl:if>
  </xsl:for-each>
 </xsl:variable>
 <xsl:copy-of select="$classificationJppc"/>
 </fieldOfSearch>
 ..
 ..

这将执行合并、排序和重复数据删除,以便:

<fieldOfSearch>
<classificationJp tsip:action="replace">
 <jppc tsip:rangeFrom="3">A61C-5/10</jppc>
 <jppc tsip:rangeTo="3">A61C-5/12</jppc>
 <jppc tsip:rangeFrom="2">A61C-8/00</jppc>
 <jppc tsip:rangeTo="2">A61C-13/38</jppc>
 <jppc tsip:rangeFrom="1">A61C-5/18</jppc>
 <jppc tsip:rangeTo="1">A61C-5/120</jppc>
 <jppc tsip:rangeFrom="1">A61C-5/15</jppc>
 <jppc tsip:rangeTo="1">A61C-5/16</jppc>
 <jppc>A61C-13/39</jppc>
 <jppc>A61C-13/40</jppc>
</classificationJp>
</fieldOfSearch>

带有 tsip:rangeFrom 和 tsip:rangeTo 的行通过具有相同属性值的 隐式链接在一起!

我还需要做的是重新编号保持隐式链接的行,以便:

<fieldOfSearch>
<classificationJp tsip:action="replace">
 <jppc tsip:rangeFrom="1">A61C-5/10</jppc>
 <jppc tsip:rangeTo="1">A61C-5/12</jppc>
 <jppc tsip:rangeFrom="2">A61C-8/00</jppc>
 <jppc tsip:rangeTo="2">A61C-13/38</jppc>
 <jppc tsip:rangeFrom="3">A61C-5/18</jppc>
 <jppc tsip:rangeTo="3">A61C-5/120</jppc>
 <jppc tsip:rangeFrom="4">A61C-5/15</jppc>
 <jppc tsip:rangeTo="4">A61C-5/16</jppc>
 <jppc>A61C-13/39</jppc>
 <jppc>A61C-13/40</jppc>
</classificationJp>
</fieldOfSearch>

但我不知道该怎么做。

请帮忙!

下面是一个最小化的示例,您可以根据需要进行调整:

.XML

<memberP xmlns:tsip="http://example.com/tsip">
  <patent>
    <patentCitations tsip:action="replace">
      <fieldOfSearch>
        <classificationJp tsip:action="replace">
          <jppc tsip:rangeFrom="1">A61C-5/18</jppc>
          <jppc tsip:rangeTo="1">A61C-5/120</jppc>
          <jppc tsip:rangeFrom="2">A61C-8/00</jppc>
          <jppc tsip:rangeTo="2">A61C-13/38</jppc>
          <jppc tsip:rangeFrom="3">A61C-5/10</jppc>
          <jppc tsip:rangeTo="3">A61C-5/12</jppc>
          <jppc>A61C-13/39</jppc>
          <jppc>A61C-13/40</jppc>
          <jppc>A61C-13/39</jppc>
        </classificationJp>
      </fieldOfSearch>
    </patentCitations>
  </patent>
  <patent>
    <patentCitations tsip:action="replace">
      <fieldOfSearch>
        <classificationJp tsip:action="replace">
          <jppc tsip:rangeFrom="1">A61C-5/15</jppc>
          <jppc tsip:rangeTo="1">A61C-5/16</jppc>
          <jppc>A61C-13/39</jppc>
          <jppc>A61C-13/40</jppc>
          <jppc>A61C-13/39</jppc>
        </classificationJp>
      </fieldOfSearch>
    </patentCitations>
  </patent>
</memberP>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tsip="http://example.com/tsip">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="citedJpcc" match="jppc" use="."/>
<xsl:template match="memberP">
    <fieldOfSearch>    
        <classificationJp tsip:action="replace">
            <!-- for each distinct jppc  -->
            <xsl:for-each select="patent/patentCitations/fieldOfSearch/classificationJp/jppc[generate-id()=generate-id(key('citedJpcc', .))]">
                <xsl:sort select="@tsip:rangeFrom | @tsip:rangeTo" data-type="number" order="descending"/>
                <xsl:copy>
                    <!-- renumber attributes  -->
                    <xsl:variable name="i" select="floor((position() + 1) div 2)" />
                    <xsl:for-each select="@tsip:rangeFrom | @tsip:rangeTo">
                        <xsl:attribute name="{name()}">
                            <xsl:value-of select="$i" />
                        </xsl:attribute>
                    </xsl:for-each>
                    <!-- copy content  -->
                    <xsl:value-of select="." />
                </xsl:copy>
            </xsl:for-each>
        </classificationJp>
    </fieldOfSearch>
</xsl:template>
</xsl:stylesheet>

结果

<?xml version="1.0" encoding="UTF-8"?>
<fieldOfSearch xmlns:tsip="http://example.com/tsip">
   <classificationJp tsip:action="replace">
      <jppc tsip:rangeFrom="1">A61C-5/10</jppc>
      <jppc tsip:rangeTo="1">A61C-5/12</jppc>
      <jppc tsip:rangeFrom="2">A61C-8/00</jppc>
      <jppc tsip:rangeTo="2">A61C-13/38</jppc>
      <jppc tsip:rangeFrom="3">A61C-5/18</jppc>
      <jppc tsip:rangeTo="3">A61C-5/120</jppc>
      <jppc tsip:rangeFrom="4">A61C-5/15</jppc>
      <jppc tsip:rangeTo="4">A61C-5/16</jppc>
      <jppc>A61C-13/39</jppc>
      <jppc>A61C-13/40</jppc>
   </classificationJp>
</fieldOfSearch>

注意:我对你删除所有重复项感到有点困惑。范围值是否不可能巧合地具有有效的重复项,例如:

<jppc tsip:rangeFrom="1">A</jppc>
<jppc tsip:rangeTo="1">B</jppc>
<jppc tsip:rangeFrom="2">B</jppc>
<jppc tsip:rangeTo="2">C</jppc>

添加:

根据评论中的澄清,我建议您尝试以下方法:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tsip="http://example.com/tsip"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="single" match="jppc[not(@tsip:rangeFrom or @tsip:rangeTo)]" use="."/>
<xsl:key name="range" match="range" use="concat(@from, '|', @to)"/>
<xsl:template match="memberP">
    <fieldOfSearch>    
        <classificationJp tsip:action="replace">
            <!-- handle ranges first -->
            <xsl:variable name="ranges">
                <xsl:for-each select="patent/patentCitations/fieldOfSearch/classificationJp/jppc[@tsip:rangeFrom]">
                    <range from="{.}" to="{following-sibling::jppc[1]}"/>
                </xsl:for-each>
            </xsl:variable>
            <!-- for each distinct range  -->
            <xsl:for-each select="exsl:node-set($ranges)/range[generate-id()=generate-id(key('range', concat(@from, '|', @to)))]">
                <!-- reconstruct and renumber  -->
                <jppc tsip:rangeFrom="{position()}">
                    <xsl:value-of select="@from"/>
                </jppc>
                <jppc tsip:rangeTo="{position()}">
                    <xsl:value-of select="@to"/>
                </jppc>
            </xsl:for-each>
            <!-- add singles (distinct only) -->
            <xsl:copy-of select="patent/patentCitations/fieldOfSearch/classificationJp/jppc[not(@tsip:rangeFrom or @tsip:rangeTo)][generate-id()=generate-id(key('single', .))]"/>
        </classificationJp>
    </fieldOfSearch>
</xsl:template>
</xsl:stylesheet>

应用于以下测试输入:

.XML

<memberP xmlns:tsip="http://example.com/tsip">
  <patent>
    <patentCitations tsip:action="replace">
      <fieldOfSearch>
        <classificationJp tsip:action="replace">
          <jppc tsip:rangeFrom="1">A</jppc>
          <jppc tsip:rangeTo="1">B</jppc>
          <jppc tsip:rangeFrom="2">B</jppc>
          <jppc tsip:rangeTo="2">C</jppc>
          <jppc tsip:rangeFrom="3">C</jppc>
          <jppc tsip:rangeTo="3">D</jppc>
          <jppc>A</jppc>
          <jppc>B</jppc>
          <jppc>C</jppc>
        </classificationJp>
      </fieldOfSearch>
    </patentCitations>
  </patent>
  <patent>
    <patentCitations tsip:action="replace">
      <fieldOfSearch>
        <classificationJp tsip:action="replace">
          <jppc tsip:rangeFrom="1">D</jppc>
          <jppc tsip:rangeTo="1">E</jppc>
          <jppc tsip:rangeFrom="2">B</jppc>
          <jppc tsip:rangeTo="2">C</jppc>
          <jppc>D</jppc>
          <jppc>B</jppc>
          <jppc>C</jppc>
        </classificationJp>
      </fieldOfSearch>
    </patentCitations>
  </patent>
</memberP>

结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<fieldOfSearch xmlns:tsip="http://example.com/tsip">
   <classificationJp tsip:action="replace">
      <jppc tsip:rangeFrom="1">A</jppc>
      <jppc tsip:rangeTo="1">B</jppc>
      <jppc tsip:rangeFrom="2">B</jppc>
      <jppc tsip:rangeTo="2">C</jppc>
      <jppc tsip:rangeFrom="3">C</jppc>
      <jppc tsip:rangeTo="3">D</jppc>
      <jppc tsip:rangeFrom="4">D</jppc>
      <jppc tsip:rangeTo="4">E</jppc>
      <jppc>A</jppc>
      <jppc>B</jppc>
      <jppc>C</jppc>
      <jppc>D</jppc>
   </classificationJp>
</fieldOfSearch>

请注意,这不会检测到部分重叠。

相关内容

  • 没有找到相关文章