2013-02-27 4 views
3

xsl 2.0 사용 모든 대문자 텍스트를 각 노드의 첫 번째 문자 만 대문자로 변환하려고합니다. 그것들은 많은 수의 가능한 자식 요소입니다.xsl의 노드와 자식 노드에서 텍스트를 소문자로 변환

<text> text text text 
<head>BLAH <unkownTag>BLAH</unkownTag> BLAH </head> 
</text> 

내가

<text> text text text 
<head>Blah <unkownTag>Blah</unkownTag> Blah </head> 
</text> 

내가 왔어요 가장 가까운을 읽는이를 변환하고 싶습니다 나에게 결과를 제공 어떤

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="head/text()"> 
    <xsl:value-of select="concat(upper-case(substring(.,1,1)),lower-case(substring(.,2)))"/>   
</xsl:template> 

입니다

<text> text text text 
    <head>Blah <unkownTag>BLAH</unkownTag> blah </head> 
</text> 

머리의 모든 하위 노드에서 소문자 변환을 수행하려면 어떻게해야합니까?

답변

4

이 변환은 말을 구분하는 문장 부호의 원하는 결과 regardles을 생성합니다

<text> text text text 
<head>BLAH <unkownTag>BLAH</unkownTag> BLAH </head> 
</text> 

를 : 제공된 XML 문서에 적용

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

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

<xsl:template match="head//text()"> 
    <xsl:analyze-string select="." regex="\p{{L}}+"> 
    <xsl:matching-substring> 
    <xsl:value-of select= 
     "concat(upper-case(substring(.,1,1)), lower-case(substring(.,2)))"/> 
    </xsl:matching-substring> 
    <xsl:non-matching-substring> 
    <xsl:value-of select="."/> 
    </xsl:non-matching-substring> 
    </xsl:analyze-string> 
</xsl:template> 
</xsl:stylesheet> 

원하는 결과가 생성됩니다.다시 올바른 결과가 생성됩니다

<text> text text text 
<head>BLAH$<unkownTag>BLAH</unkownTag>-BLAH;</head> 
</text> 

:

<text> text text text 
<head>Blah$<unkownTag>Blah</unkownTag>-Blah;</head> 
</text> 

설명 :

이 XML 문서에 적용 663,210

<text> text text text 
<head>Blah <unkownTag>Blah</unkownTag> Blah </head> 
</text> 

  1. 지침 <xsl:analyze-string>을 올바르게 사용하십시오.

  2. 문자 클래스 \p{L}의 올바른 사용.

  3. <xsl:matching-substring><xsl:non-matching-substring> 지침을 올바르게 사용하십시오.

0

시도해보십시오. 나는 그것을 테스트하지 않았으므로 약간 조정해야 할 수도 있습니다.

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

<xsl:template match="head"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"> 
     <xsl:value-of select="concat(upper-case(substring(.,1,1)),lower-case(substring(.,2)))"/> 
    </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 
+1

불행히도 내에서 허용되지 않습니다. – user1748728

0

이렇게하면 도움이 될 수 있습니다. 형제 텍스트 노드 총액은 올바른 얻기에 약간의 증가 어려움이있을 수 있도록하지만 세 번째 "BLAH"확실하지

<xsl:template match="/"> 
    <xsl:apply-templates select="node()" mode="firstup"/> 
</xsl:template> 

<xsl:template match="text()" mode="firstup"> 
    <!--<x>--> 
    <xsl:value-of select="concat(upper-case(substring(.,1,1)),lower-case(substring(.,2)))"/> 
    <!--</x>--> 
</xsl:template> 

이 텍스트() 노드가 공백으로 시작합니다. 이를 보시려면 "x"요소의 주석 처리를 제거하십시오. 정규화 된 공백과 position() 함수를 더 자세히 살펴볼 수도 있습니다.

1

텍스트의 공백으로 인해 흥미로운 문제가 발생했습니다. 'head'아래의 모든 text() 노드를 일치 시키려면 XPath 표현식을 사용하여 조상을 봅니다.

여기서 문자열을 토큰 화 한 다음 결과 집합을 반복하여 첫 번째 문자를 대문자로 변경하고 다음 문자를 소문자로 변경합니다.

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="text()[ ancestor::head ]"> 
     <xsl:value-of select=" 
      for $str in tokenize(., '\s') 
      return concat(upper-case(substring($str,1,1)), 
          lower-case(substring($str,2)))"/> 
    </xsl:template> 
</xsl:stylesheet> 
관련 문제