2012-01-18 3 views
3

나는 this 답변에 따라 스타일 시트를 사용하여, XSLT2 실험 해요 :XSLT2 replace() 함수에서 엔티티 변환을 어떻게 혼합하고 일치 시키나요?

<?xml version="1.0" encoding="utf-8"?> 
<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1"> 
    <file> 
    <source>abc &lt;field1&gt; def &lt;field2&gt; ghi</source> 
    </file> 
</xliff> 

에 :

<?xml version="1.0" encoding="utf-8"?> 
<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1"> 
    <file> 
    <source>abc <ph>&lt;field1&gt;</ph> def <ph>&lt;field2&gt;</ph> ghi</source> 
    </file> 
</xliff> 
것입니다

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="source/text()"> 
    <xsl:sequence select="replace(., '&lt;.*?&gt;', '<ph>$0</ph>')"/> 
</xsl:template> 
</xsl:stylesheet> 

여러 대체 예에서 할

하지만 변환이 유효하지 않습니다.이 오류가 발생합니다.

Error on line 12 column 54 of my.xsl: 
    SXXP0003: Error reported by XML parser: The value of attribute "select" associated with an 
    element type "null" must not contain the '<' character. 

select="replace(., '&lt;(.*?)&gt;', '&lt;ph&gt;F&lt;/phgt;')"을 사용하는 경우 출력에 ...&lt;ph&gt;...이 표시됩니다.

DOE을 사용하는 경우 현장에 다른 항목이있을 수 있으므로 다른 문제를 소개합니다. 손길이 닿지 않으려 고합니다. <xsl:output method="text"/>을 사용하면 대부분의 XML을 잃어 버리게됩니다. 이와 같은 '믹싱 및 매칭'의 다른 방법이 있습니까?

+0

이 가능하며, 문자열 대체는 아닙니다. –

답변

4

문제는 여기입니다 :

<xsl:sequence select="replace(., '&lt;(.*?)&gt;', '<ph>F</ph>')"/> 

잘 구성된 XML 문서 속성 값< 문자를 포함 할 수 없습니다.

위의 경우 select 속성에 하위 문자열 <ph>F</ph>이 포함되어 있으며 이로 인해 스타일 시트가 XML 문서로 해석되지 않습니다.

더 중요한 것은 요소는 문자열 대체 ()로 생성 할 수 없습니다. 결과는 요소가 아닌 문자열 (인코딩 된 요소 표현 포함) 일뿐입니다.여기

은 당신이 원하는 것을 달성하는 방법입니다 :

<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1"> 
    <file> 
     <source>abc &lt;field1&gt; def &lt;field2&gt; ghi</source> 
    </file> 
</xliff> 
0,123,516 :이 변환이 제공된 XML 문서에 적용

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

<xsl:template match="source/text()"> 
    <xsl:analyze-string select="." regex="&lt;(.*?)&gt;"> 
    <xsl:matching-substring> 
     <ph><xsl:value-of select="regex-group(1)"/></ph> 
    </xsl:matching-substring> 
    <xsl:non-matching-substring> 
    <xsl:sequence select="."/> 
    </xsl:non-matching-substring> 
    </xsl:analyze-string> 
</xsl:template> 

가 원하는 결과가 생성됩니다

<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1"> 
     <file> 
      <source>abc <ph>field1</ph> def <ph>field2</ph> ghi</source> 
     </file> 
</xliff> 

설명 다음 XSLT의 적절한 사용 2.0 지침 <xsl:analyze-string>, <xsl:matching-substring>, <xsl:non-matching-substring>regex-group()

+0

'xsl : matching-substring'에''을 쓰지 않으시겠습니까? –

+0

필자는 실제 요구 사항에 맞게 조정했습니다. 정확하고 명확한 답변 덕분에 쉽게 해결할 수 있습니다 (@DevNull이 맞다고 생각합니다. 이전 질문에서 약간의 이월 만 :-) –

+0

@DevNull : 왜? OP 자신이 그의 질문에' F'을 사용합니다. –

1

문자열 &lt;가 원본 문서에 표시되는 경우, 문서의 XDM 트리 표현이 &lt;로 스타일 시트에 기록 된 정규식 '<를'일치 문자 그 자리에 '<'을 포함합니다 .

그래야만 작동하지만 분명히 잘못된 것이 있습니다. 우리가 한 일을 보여주고 잘못 간 곳을 말해 줄 수 있습니다. 문제가 무엇인지 알려주지 않으면 큰 문제가되지 않습니다.

+0

답변 해 주셔서 감사합니다. Michael - 저는 제가 시도한 것을 정확히 보여주기 위해 질문을 업데이트했습니다. 정규식을 사용하는 '검색'비트는 제대로 작동해야합니다.하지만 '대체'측과 관련하여 문제가 있습니다. –

+1

문제는 @ Jack-Douglas가 단순히 문자열 교체로 요소를 생성하려고한다는 것입니다. 가능한. 요소는 노드이므로 문자열의 하위 문자열이 아닌 요소로 만들어야합니다. 해결 방법은 대답과 같이''을 사용하는 것입니다. –