2011-04-09 3 views
1

XSL 1.0에서는 처리해야하는 입력 XML 내에서 발생하는 각 시나리오와 다르게 처리되는 다음 두 시나리오를 구분하려고합니다.xsl - 텍스트가 상위에 섞여있는 태그 위치

시나리오 1

<tag1><tag2/> some text</tag1> 

시나리오 2

<tag1>some text <tag2/></tag1> 

나는 시나리오 2에 내가 삽입 할, 내가 <tag2/>을 무시하는 시나리오 1을 원하는이 내에서 <tag2/> 수준에서 일치하는 템플릿을 <tag2/> 대신에 <br/>이 있습니다.

여기서는 Google에서 검색했지만 <tag2/>의 위치를 ​​기준으로 구별하는 방법을 알아낼 수 없습니다. <tag1> 내에 있습니다.

나는 이전-형제생성-ID으로 보면서 같은 것을 사용하는 것을 시도했다 : -하지 않는 것

not(
    generate-id(
     preceding-sibling::node()[1] 
    ) 
    = generate-id(
     preceding-sibling::text()[1] 
    ) 
) 

<tag2/>

position() 

을 두 노드 모두 노드 레벨에서 작동하는 것처럼 보이므로 여기에서 도우십시오.

어떤 아이디어라도 환영할만한가요?

감사 로저

+0

좋은 질문, +1. 현재 받아 들여지는 것보다 쉽고 간단하며 근본적인 해결책에 대한 내 대답을보십시오. :) –

+0

추가 된 설명을 추가했습니다. –

답변

0

다음 스타일 : 더 복잡

some text 
some text <br/> 

:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="tag2[preceding-sibling::text()]"> 
     <br/> 
    </xsl:template> 
</xsl:stylesheet> 

이 입력 중 :

<items> 
    <tag1><tag2/>some text</tag1> 
    <tag1>some text <tag2/></tag1> 
</items> 

가 생산 솔루션은 원하는 출력에 대한 추가 정보가 필요합니다. 이 패턴에서

+0

빠른 응답을 주셔서 감사합니다. 지금은 충분하다고 생각합니다. 이걸 알려 드리겠습니다. – MrChick

+0

다시 실행하면 입력란 xml에 두 시나리오의 텍스트가 있음을 알았습니다. 첫 번째 시나리오에서는 태그 사이에 새로운 줄이 있기 때문입니다. 그래서 ' \ n '이지만 솔루션을 사용하십시오. tag2 [preceding-sibling :: text() [normalize-space (string (.))]]에 추가하면 지금이 문제가 해결되었습니다. 도움에 다시 한번 감사드립니다! – MrChick

+1

@MrChick :'tag2 [preceding-sibling :: text() [normalize-space()]]'이면 충분합니다. 또한 @ Dimitre의 답변을 살펴보고 스트리밍 가능한 솔루션을 찾고 있습니다. –

1

봐 :

node()[1] 

이 일치하는 첫 번째 노드의 아이입니다.

node()[1][self::tag2] 

이 요소는 tag2 요소이기도합니다.

node()[not(self::text()[not(normalize-space())])][1][self::tag2] 

공백 전용 텍스트 노드와도 tag2 요소 (경우에 당신은 공백 전용 텍스트 노드는 XHTML 입력을해야한다 등의 보존)되지 않습니다 일치하는 첫 번째 노드의 아이입니다.

첫 번째 및 두 번째 패턴이 streamable (preceding 축이 스트림 가능하지 않음)이기 때문에이 방법을 사용합니다.

참고 : 두 번째는 node()[position() = 1 and self::tag2]으로 다시 작성해야합니다.

0

단순하고 근본적인 해결책이 XML 문서에 적용

<xsl:stylesheet version="1.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= 
    "node()[self::tag2 and position()=1]"/> 
<xsl:template match= 
    "node()[self::tag2 and position()=2]"> 
    <br/> 
</xsl:template> 
</xsl:stylesheet> 

:

<tag1> some text</tag1> 
:

<tag1><tag2/> some text</tag1> 

이 원하는 정확한 결과를 생성3210

이 문서에 적용하는 경우 : 다시

<tag1>some text <tag2/></tag1> 

원하는, 정답은을 생성됩니다

<tag1>some text <br/> 
</tag1> 

설명 :

  1. 신원 규칙을 (테 mplate)는 모든 노드를있는 그대로 복사합니다.

  2. 신원 규칙을 무시하는 첫 번째 템플리트는 이름이 tag2이고 노드 목록의 위치가 1 인 모든 노드와 일치합니다. 몸체가 없으므로 tag2 요소는 무시됩니다.

  3. 신원 규칙을 무시하는 두 번째 템플리트는 첫 번째 템플리트와 유사하지만 일치하는 tag2 노드의 위치는 2 여야합니다.이 경우 <br/>으로 바뀝니다.

+0

네, 새로운 스트리밍 가능한 조건을 따르기 때문에이 경로로 이동합니다. –