我有一个无法修复的 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>
请注意,这不会检测到部分重叠。