2015-09-05 42 views
0

請建議如何從除「聯機」部分以外的所有外部參照獲取最大「清除」值。通過識別最大值'rid',然後需要將這個屬性插入到那些高於最大值的引用。請參閱所需的結果文本。如何獲得除特定部分以外的最大外部參照值「除外」

XML:

<article> 
<body> 
    <sec><title>Sections</title> 
    <p>The test <xref rid="b1">1</xref>, <xref rid="b2">2</xref>, <xref rid="b3 b4 b5">3-5</xref></p></sec> 
    <sec><title>Online</title><!--This section's xrefs no need to consider--> 
     <p>The test <xref rid="b6">6</xref></p> 
     <sec><title>Other</title> 
      <p><xref rid="b1">1</xref>, <xref rid="b7 b8">7-8</xref></p> 
     </sec> 
    </sec><!--This section's xrefs no need to consider--> 
    <sec> 
     <p>Final test test</p> 
     <sec><title>Third title</title><p>Last text</p></sec> 
    </sec> 
</body> 
<bm> 
    <ref id="b1">The ref01</ref> 
    <ref id="b2">The ref02</ref> 
    <ref id="b3">The ref03</ref> 
    <ref id="b4">The ref04</ref> 
    <ref id="b5">The ref05</ref> 
    <ref id="b6">The ref06</ref> 
    <ref id="b7">The ref07</ref> 
    <ref id="b8">The ref08</ref> 
</bm> 
</article> 

XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

<xsl:variable name="var1"><!--Variable to get the all 'rid's except sec/title contains 'Online' --> 
    <xsl:for-each select="//xref[not(. is ancestor::sec[title[contains(., 'Online')]]/descendant-or-self)]/@rid"> 
    <!--xsl:for-each select="//xref/@rid[not(contains(ancestor::sec/title, 'Online'))]"--><!--for this xpath, error is : "XPTY0004: A sequence of more than one item is not allowed as the first argument" --> 
    <!--xsl:for-each select="//xref/@rid[not(contains(ancestor::sec[1]/title, 'Online')) and not(contains(ancestor::sec[2]/title, 'Online'))]"--><!--for this xpath we are getting the required result, but there may be several nesting of 'sec's --> 
     <xsl:choose> 
      <xsl:when test="contains(., ' ')"> 
       <xsl:for-each select="tokenize(., ' ')"> 
        <a><xsl:value-of select="."/></a> 
       </xsl:for-each> 
      </xsl:when> 
      <xsl:otherwise><a><xsl:value-of select="."/></a></xsl:otherwise> 
     </xsl:choose> 
    </xsl:for-each> 
</xsl:variable> 
<xsl:variable name="varMax1"> 
    <xsl:for-each select="$var1/a"> 
     <xsl:sort select="substring-after(., 'b')" order="descending" data-type="number"/> 
     <a><xsl:value-of select="."/></a> 
    </xsl:for-each> 
</xsl:variable> 

<xsl:variable name="varMax"><!--Variable to get max valued RID --> 
    <xsl:value-of select="substring-after($varMax1/a[1], 'b')"/> 
</xsl:variable> 

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

<xsl:template match="ref"> 
    <xsl:variable name="varID"><xsl:value-of select="substring-after(@id, 'b')"/></xsl:variable> 
    <xsl:choose> 
     <xsl:when test="number($varMax) lt number($varID)"> 
      <xsl:copy> 
       <xsl:apply-templates select="@*"/> 
       <xsl:attribute name="MoveRef">yes</xsl:attribute> 
       <xsl:apply-templates select="node()"/> 
      </xsl:copy> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

要求的結果:

<article> 
<body> 
    <sec><title>Sections</title> 
    <p>The test <xref rid="b1">1</xref>, <xref rid="b2">2</xref>, <xref rid="b3 b4 b5">3-5</xref></p></sec> 
    <sec><title>Online</title><!--This section's xrefs no need to consider--> 
     <p>The test <xref rid="b6">6</xref></p> 
     <sec><title>Other</title> 
      <p><xref rid="b1">1</xref>, <xref rid="b7">7</xref>, <xref rid="b8">8</xref></p> 
     </sec> 
    </sec><!--This section's xrefs no need to consider--> 
    <sec> 
     <p>Final test test</p> 
     <sec><title>Third title</title><p>Last text</p></sec> 
    </sec> 
</body> 
<bm> 
    <ref id="b1">The ref01</ref> 
    <ref id="b2">The ref02</ref> 
    <ref id="b3">The ref03</ref> 
    <ref id="b4">The ref04</ref> 
    <ref id="b5">The ref05</ref> 
    <ref id="b6" MoveRef="yes">The ref06</ref> 
    <ref id="b7" MoveRef="yes">The ref07</ref> 
    <ref id="b8" MoveRef="yes">The ref08</ref> 
</bm> 
</article> 

這裏考慮數5「B 5'rid,6 for'b6'...(因爲字母數字)

回答

1

也許您可以採取不同的方法,而不是試圖找到不在「在線」部分中的最大rid屬性。尤其是因爲在處理字母數字字符串時,最大限度不明確。

相反,你可以定義一個鍵按名稱來查找「在線」欄目中的元素

<xsl:key name="online" match="sec[title = 'Online']//*" use="name()" /> 

然後,另一個關鍵,查找發生在其他部分

xref元素
<xsl:key name="other" match="xref[not(ancestor::sec/title = 'Online')]" use="name()" /> 

然後,你可以寫一個模板,數學的ref元素,並使用xsl:if以確定是否MoveRef屬性添加到它:

<xsl:variable name="id" select="@id" /> 
<xsl:if test="key('online', 'xref')[tokenize(@rid, ' ')[. = $id]] and not(key('other', 'xref')[tokenize(@rid, ' ')[. = $id]])"> 

試試這個短得多XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:key name="online" match="sec[title = 'Online']//*" use="name()" /> 
    <xsl:key name="other" match="xref[not(ancestor::sec/title = 'Online')]" use="name()" /> 

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

    <xsl:template match="ref"> 
     <ref> 
      <xsl:variable name="id" select="@id" /> 
      <xsl:if test="key('online', 'xref')[tokenize(@rid, ' ')[. = $id]] and not(key('other', 'xref')[tokenize(@rid, ' ')[. = $id]])"> 
       <xsl:attribute name="MoveRef" select="'Yes'" /> 
      </xsl:if> 
      <xsl:apply-templates select="@*|node()"/> 
     </ref> 
    </xsl:template> 
</xsl:stylesheet> 

實際上,你可以修改ref模板把條件模板匹配,如果你想...

<xsl:template match="ref[key('online', 'xref')[tokenize(@rid, ' ')[. = current()/@id]] and not(key('other', 'xref')[tokenize(@rid, ' ')[. = current()/@id]])]"> 
    <ref MoveRef="Yes"> 
     <xsl:apply-templates select="@*|node()"/> 
    </ref> 
</xsl:template> 
+0

感謝的建議,但如果範圍類型像 7-8,那麼我們沒有得到所需的結果。 –

+0

@RudramuniTP - 我已經修改了我的答案來應對這種情況。在你的XML中顯示一個「」的例子可能是值得修改你的問題的。謝謝。 –

+0

非常感謝您的完美建議,按需完美工作。加一... –