2012-02-28 3 views
1

트리에서 동일한 이름을 가진 노드로 노드를 대체하는 방법을 찾고 있습니다. 예를 들어, 다음과 같은 입력과 :XSLT 2.0 : 손자 노드로 노드 오버라이드

<root> 
    <foo> 
     <a>1</a> 
     <b>2</b> 
     <c>3</c> 
     <bar> 
      <a>100</a> 
      <c>5000</c> 
     </bar> 
    </foo> 
</root> 

나는 이런 식으로 뭔가 생산하고 싶습니다 : 나는 임의의 수의 노드를 교체 할 수 있어야

<root> 
    <foo> 
     <a>100</a> 
     <b>2</b> 
     <c>5000</c> 
    </foo> 
</root> 

, 그리고 나 또한 싶습니다 미래에 상황이 바뀔 가능성이 있기 때문에 모든 가능성을 설명하기보다는 목록을 동적으로 파악하는 것이 중요합니다. 또 하나의 요구 사항은 상위 노드의 순서가 그대로 유지되어야한다는 것입니다. (구체적으로 말하자면, 필자의 최종 결과물은 CSV 파일이므로 컬럼은 헤더와 정렬되어야합니다.)

이것은 XSLT를 배우는 첫 번째 시도이며, 나는이 문제에 완전히 걸려 있습니다! 어떤 도움이라도 대단히 감사하겠습니다. 나는 XSLT 2.0을 사용하고있다.

감사합니다, 마크

답변

0

나는 형식의 코드를 들여 쓰기를하지 않는 불쾌한 SO 버그에 대해 사과!

그들은

... 개월이 변환을이 문제를 해결할 수 없습니다

<root> 
    <foo> 
     <a>1</a> 
     <b>2</b> 
     <c>3</c> 
     <bar> 
      <a>100</a> 
      <c>5000</c> 
     </bar> 
    </foo> 
</root> 

: 제공된 XML 문서에 적용

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match= 
"*[*] 
     [every $leaf in .//*[not(*)] 
     satisfies 
     name($leaf) = preceding::*/name() 
     ] 
"/> 

<xsl:template match= 
    "*[not(*) and name() = following::*/name()]"> 

    <xsl:sequence select= 
    "following::*[name() = name(current())][1]"/> 
</xsl:template> 
</xsl:stylesheet> 

원하는 결과를 얻는다. :

<root> 
    <foo> 
     <a>100</a> 
     <b>2</b> 
     <c>5000</c> 
    </foo> 
</root> 
+0

거룩한 암소! 나는 그것을 스스로 알아낼 수 없을 정도로 나쁘다고 느끼지 않습니다. 그것은 매력처럼 작동합니다. 많은 감사합니다! – donkey

+0

@donkey : 천만에요. –