2017-12-07 15 views
1

入力カット

<items> 
    <item>Lorem ipsum dolor sit amet, sed diam nonumy tempor magna aliquyam erat. Ssed diam voluptua.</item> 
    <item>Lorem ipsum dolor sit amet, sed diam nonumy<br/>tempor magna aliquyam erat. Ssed diam voluptua.</item> 
    <item>Lorem ipsum dolor sit amet, sed diam nonumy <b>tempor magna aliquyam erat</b>. Ssed diam voluptua.</item> 
    <item>Lorem ipsum dolor sit amet, sed diam nonumy <b>tempor <i>magna</i> aliquyam erat</b>. Ssed diam voluptua.</item> 
    <item>Lorem ipsum dolor sit amet.</item> 
</items> 

要件

  • 例えば、特定の長さの後後に最も近い単語を "カット" 25文字(税込。空白)
  • 位置は属性foo="bar"
  • template with mode='xy'(これによって処理されている位置後のすべてのtext()を取得
  • すべて*手つかずある位置前にすべてのnodes()は、テンプレートはテキストを醜くします)。 text() -nodesは、[4]の項目を参照particial可読で/、*をuglifiedこれらtext() -nodes新しい要素<o foo="bar">内に包まれている場合、テンプレートは、「#」
  • として<o foo="bar"> +自体内のすべての隣接text() -nodesをラップ=> "aliquyamのERAT"] string-length(text()) le $visibleCharsあれば、何も

出力

<!-- middle of word "temppor" --> 
<xsl:variable name="visibleChars" select="number(48)"/> 
<items> 
    <item>Lorem ipsum dolor sit amet, sed diam nonumy tempor<o foo="bar"> #</o></item> 
    <item>Lorem ipsum dolor sit amet, sed diam nonumy<br/>tempor<o foo="bar"> #</o></item> 
    <item>Lorem ipsum dolor sit amet, sed diam nonumy <b>tempor<o foo="bar">#</o></b><o foo="bar">#</o></item> 
    <item>Lorem ipsum dolor sit amet, sed diam nonumy <b>tempor <i foo="bar">#</i><o foo="bar"> #</o></b><o foo="bar">#</o></item> 
    <item>Lorem ipsum dolor sit amet.</item> 
</items> 
を起こりません '#'
  • としての地位を

    失敗した擬似XSLT

    <xsl:templates match="item"> 
        WHEN count(text()) eq count(node()) 
        THEN 
        Create a $temp of <item> AND insert a <cut/> at position ($visibleChars + CharsTillNextDelimiter) 
        <!-- chars to stay visible --> 
        <xsl:apply-templates select="$temp/text()[following-sibling::cut]"/> 
        <!-- chars to uglify --> 
        <xsl:apply-templates select="$temp/text()[preceding-sibling::cut]" mode="xy"/> 
    
        WHEN (*) 
        THEN 
        NoIDEAToTackleMixedContentFields 
    
    ... 
    <xsl:template match="text()" mode="xy"> 
    
        <xsl:analyze-string select="." regex="[a-zA-Z0-9]"> 
         <xsl:matching-substring> 
          <xsl:text>#</xsl:text> 
         </xsl:matching-substring> 
         <xsl:non-matching-substring> 
          <xsl:value-of select="."/> 
         </xsl:non-matching-substring> 
        </xsl:analyze-string> 
    </xsl:template> 
    ... 
    

    私が実行して縮小さXSLTを持っていないが、それにもかかわらず、誰かが私の要件を満たすための方法が表示される場合があります。どのような助けもありがとうございます。次のように

  • 答えて

    1

    私はcut要素を挿入するようにして、修正itemを処理するために管理している:あなたが投稿何

    <?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:functx="http://www.functx.com" 
        exclude-result-prefixes="xs functx" version="2.0"> 
    
        <xsl:param name="length" select="48"/> 
    
        <xsl:function name="functx:escape-for-regex" as="xs:string"> 
         <xsl:param name="arg" as="xs:string?"/> 
    
         <xsl:sequence 
          select=" 
           replace($arg, 
           '(\.|\[|\]|\\|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))', '\\$1') 
           "/> 
    
        </xsl:function> 
    
        <xsl:template match="@* | node()" mode="#all"> 
         <xsl:copy> 
          <xsl:apply-templates select="@* | node()" mode="#current"/> 
         </xsl:copy> 
        </xsl:template> 
    
        <xsl:template match="item[string-length() gt $length]"> 
         <xsl:variable name="head" as="xs:string" select="substring(., 1, $length)"/> 
         <xsl:variable name="head-pattern" as="xs:string" 
          select="concat('^', functx:escape-for-regex($head), '\S*')"/> 
         <xsl:variable name="text-to-cut" as="text()" 
          select="descendant::text()[matches(string-join((preceding::text()[. >> current()], .), ''), $head-pattern)][1]"/> 
         <xsl:variable name="splitted-text" as="xs:string*"> 
          <xsl:analyze-string select="$text-to-cut" 
           regex="{if ($text-to-cut is (current()//text())[1]) then $head-pattern else '^\S+'}"> 
           <xsl:matching-substring> 
            <xsl:sequence select="."/> 
           </xsl:matching-substring> 
           <xsl:non-matching-substring> 
            <xsl:sequence select="."/> 
           </xsl:non-matching-substring> 
          </xsl:analyze-string> 
         </xsl:variable> 
         <xsl:variable name="modified-copy" as="element(item)"> 
          <xsl:copy> 
           <xsl:apply-templates mode="modify"> 
            <xsl:with-param name="text-to-cut" as="text()" select="$text-to-cut" 
             tunnel="yes"/> 
            <xsl:with-param name="splitted-text" as="xs:string*" select="$splitted-text" 
             tunnel="yes"/> 
           </xsl:apply-templates> 
          </xsl:copy> 
         </xsl:variable> 
         <xsl:message select="'modified-copy', $modified-copy"/> 
         <xsl:apply-templates select="$modified-copy" mode="cut"/> 
        </xsl:template> 
    
        <xsl:template match="item//text()" mode="modify"> 
         <xsl:param name="text-to-cut" as="text()" tunnel="yes"/> 
         <xsl:param name="splitted-text" as="xs:string*" tunnel="yes"/> 
         <xsl:choose> 
          <xsl:when test=". is $text-to-cut"> 
           <xsl:value-of select="$splitted-text[1]"/> 
           <cut/> 
           <xsl:value-of select="$splitted-text[2]"/> 
          </xsl:when> 
          <xsl:otherwise> 
           <xsl:next-match/> 
          </xsl:otherwise> 
         </xsl:choose> 
        </xsl:template> 
    
        <xsl:template match="cut" mode="cut"/> 
    
        <xsl:template match="*[preceding-sibling::cut]" mode="cut"> 
         <xsl:copy> 
          <xsl:attribute name="foo">bar</xsl:attribute> 
          <xsl:apply-templates mode="#current"/> 
         </xsl:copy> 
        </xsl:template> 
    
        <xsl:template match="text()[preceding::cut]" mode="cut"> 
         <o foo="bar"> 
          <xsl:analyze-string select="." regex="[a-zA-Z0-9]+"> 
           <xsl:matching-substring> 
            <xsl:text>#</xsl:text> 
           </xsl:matching-substring> 
           <xsl:non-matching-substring> 
            <xsl:value-of select="."/> 
           </xsl:non-matching-substring> 
          </xsl:analyze-string> 
         </o> 
        </xsl:template> 
    
    </xsl:stylesheet> 
    

    私はあなたの入力を取得し、結果はかなりありませんが、近いので、私はあなたが適応することを願ってその:

    <items> 
        <item>Lorem ipsum dolor sit amet, sed diam nonumy tempor<o foo="bar"> # # #. # # #.</o></item> 
        <item>Lorem ipsum dolor sit amet, sed diam nonumy<br/>tempor<o foo="bar"> # # #. # # #.</o></item> 
        <item>Lorem ipsum dolor sit amet, sed diam nonumy <b>tempor<o foo="bar"> # # #</o></b><o foo="bar">. # # #.</o></item> 
        <item>Lorem ipsum dolor sit amet, sed diam nonumy <b>tempor<o foo="bar"> </o><i foo="bar"><o foo="bar">#</o></i><o foo="bar"> # #</o></b><o foo="bar">. # # #.</o></item> 
        <item>Lorem ipsum dolor sit amet.</item> 
    </items> 
    
    +0

    これは重い正規表現ベースのソリューションです(重い文字列操作の質問です)。しかし、後で試してみましょう。解決に時間をとってくれてありがとう。 – uL1

    0

    私は最も簡単な方法のように他のすべてを排除するための唯一の共通の特殊文字の文字列になることだと思うが「、」、下記をご覧ください。

    その結果
    <?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >  
    <xsl:output method="xml" version="4.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />  
    <xsl:template match="/"> 
        <items> 
         <xsl:for-each select="items/item"> 
          <item> 
           <xsl:variable name="main.string" select="."/> 
           <!--transform string with only one delimiter--> 
           <xsl:variable name="format.string" select="translate(normalize-space($main.string), ' ,.', '|')"/> 
           <!--get string till 25th character--> 
           <xsl:variable name="format.limit.string" select="substring(normalize-space($main.string), 0, 24)"/> 
           <!--get 25th character--> 
           <xsl:variable name="format.last.char" select="translate($format.limit.string, substring($format.limit.string, 0, 23), '')"/>  
           <!--check if the 25th character is delimiter or part of the word--> 
           <xsl:choose> 
            <xsl:when test="$format.last.char = '|'"> 
             <xsl:value-of select="substring(normalize-space($format.limit.string), 0, 23)"/> 
             <xsl:element name="o"> 
             <xsl:attribute name="foo"><xsl:value-of select="'bar'"/></xsl:attribute> 
             </xsl:element> 
             <xsl:value-of select="substring($main.string, 24, string-length($main.string))"/> 
            </xsl:when> 
            <xsl:otherwise> 
             <!--if cut in the middle of the word then rest part will be added--> 
             <xsl:variable name="final.string" select="concat($format.limit.string, substring-before(substring($format.string, 24, string-length($format.string)), '|'))"/> 
             <xsl:value-of select="$final.string"/>       
             <xsl:element name="o"> 
             <xsl:attribute name="foo"><xsl:value-of select="'bar'"/></xsl:attribute> 
             </xsl:element> 
             <xsl:value-of select="substring($main.string, string-length($final.string)+1, string-length($main.string))"/> 
            </xsl:otherwise>   
           </xsl:choose> 
          </item> 
         </xsl:for-each> 
        </items>    
    </xsl:template> 
    </xsl:stylesheet> 
    

    あなたは25文字(ワードまで)を使用して制限を持っています - 他の化粧品の事は私のコードでconcat関数によって追加することが可能です:

    <items> 
        <item>Lorem ipsum dolor sit amet<o foo="bar"/>, sed diam nonumy tempor magna aliquyam erat. Ssed diam voluptua.</item> 
        <item>Lorem ipsum dolor sit amet<o foo="bar"/>, sed diam nonumytempor magna aliquyam erat. Ssed diam voluptua.</item> 
        <item>Lorem ipsum dolor sit amet<o foo="bar"/>, sed diam nonumy tempor magna aliquyam erat. Ssed diam voluptua.</item> 
        <item>Lorem ipsum dolor sit amet<o foo="bar"/>, sed diam nonumy tempor magna aliquyam erat. Ssed diam voluptua.</item> 
        <item>Lorem ipsum dolor sit amet<o foo="bar"/>.</item> 
    </items> 
    

    はそれに役立つことを願っています。