我遇到了无法解决的XSLT问题。
我有以下XML XML片段:
<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>
..
..
我需要做的是基于tsip:rangeFrom和tsip:rangeTo属性值进行合并,重复数据删除,排序和重新编号!
使用以下代码段:
<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>
这会进行合并,排序和重复数据删除:
<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>
具有tsip的行:rangeFrom和tsip:rangeTo通过具有相同的属性值隐式链接在一起!
我还需要做的是重新编号保持隐式链接的行,以便:
{{1}}
但我不知道该怎么做。
请帮忙!
答案 0 :(得分:1)
这是一个可以适应您需求的最小化示例:
<强> 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>
请注意,这不会检测到部分重叠。