2012-07-17 1 views
1

Google에서 답변을 찾으려고했지만 그 결과는 문자열을 대체하거나 하위 문자열을 대체하는 방법 중 하나입니다.하지만 제 질문은 약간 다릅니다. 들어오는 XSL 데이터를 바꾸거나 대체 할 수 있습니까?

내가 기존 XSL 템플릿이 말, 말 " 안녕하세요 세계" "데이터/기록/기록을"처리,하지만 난 안녕하세요 세계 수정할 수 없습니다, 그래서 내가 만드는 생각 해요 안녕하세요 - 세계에 전달하기 전에 각 레코드 내부의 데이터를 마사지/수정하는 래퍼 템플릿 ...이 방법이 있습니까?

지금까지, 나는 중복 레코드를 필터링 할 함수를 작성하기 위해 관리했습니다, 나는 ... 새로운 하나 "/ * 데이터/기록"내부의 모든 레코드를 대체하는 생각

<xsl:variable name="/data/records/record"> 
    <xsl:call-template name="get-unique-record"> 
     <xsl:with-param name="records" select="/data/records/record"/> 
    </xsl:call-template> 
</xsl:variable> 

편집 : @LasrH, 빠른 답장을 보내 주셔서 감사합니다

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 


    <xsl:template match="/"> 
     <xsl:call-template name="get-unique-record"> 
      <xsl:with-param name="records" select="/data/records/record"/> 
     </xsl:call-template> 
    </xsl:template> 

    <!-- This function will filter out the given records and return a unique set of records --> 
    <xsl:key name="kField_ID" match="field[@name='ID']" use="."/> 
    <xsl:template name="get-unique-record"> 
     <xsl:param name="records"/> 
     <xsl:for-each select="$records"> 
      <xsl:variable name="record" select="."/> 
      <xsl:if test="$record//field[generate-id() = generate-id(key('kField_ID', .))]"> 
      <xsl:copy-of select="$record"/>   
      </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 

지금 ... 그것이 가능 뭔가를하는 것입니다. 기존의 "/"복사본을 만든 다음 모든/data/records/레코드를 필터링 된 것으로 바꾸는 방법이 있습니까?

EDIT2 : @LasrH, 나는 "데이터"노드를 수정하고 다시 작성하기 위해 몇 개의 템플릿을 만들었습니다. 노드 집합을 사용하여 기존 입력을 새 데이터로 입력을 "대체"할 수 있습니까?

<xsl:variable name="data"> 
    <xsl:call-template name="rebuild-data-with-record"> 
     <xsl:with-param name="records"> 
        <xsl:copy-of select="$unique-records"></xsl:copy-of> 
        </xsl:with-param> 
    </xsl:call-template> 
</xsl:variable> 

그럼 더 아래로 난 노드 집합을 다음과 같이 사용하려고 :

<xsl:apply-templates select="exslt:node-set($data)/data"/> 

하지만 중 하나를 던져 오류가없는 ... 그 일처럼 보이지 않는다.

+0

"기능"보다는 "템플릿"을 사용하는 것처럼 보입니다. – LarsH

+0

고정, 그렇지, 나는 C/Java 프로그래머 롤, 오직 XSL을 조사하기 시작했다. 나쁜 용어에 대해 유감스럽게 생각합니다. 텍스트를 업데이트했습니다. :) – codenamezero

+0

문제 없습니다 ... 템플릿과 다른 XSLT의 함수가 있기 때문에 주로 문제가됩니다. – LarsH

답변

1

실제로 많은 연구와 시험을 거친 후 XSL 수준에서 데이터를 "대체/대체"할 수 있습니다 !!! 루트 노드를 스스로 재구성하고 "수정 된 루트"(RTF가 노드 집합으로 다시 캐스팅)를 템플릿에 전달하고 템플릿이 자신의 데이터를 대신 읽도록하십시오 !!!

나는이 작업을 얻을 내 실험의 일환이었다, 여기에 또 다른 질문을했다 : Unable to cast from XRTreeFrag into XNodeSet

아이디어는 이것이다, 당신은 수신 데이터/거래를 읽을 템플릿 기능이, 예쁜 우리 많은 항상 루트/ㅋ/ㅋ/ㅋ 오프 입력을 읽어 ... 오히려 루트 떨어져 그것을 읽는 것보다, 당신은 모든이 작업을 수행 할 수 있습니다/템플릿의 어떤은 :

<xsl:template name="helloworld"> 
    <xsl:param name="inputRoot" select="/"/> 
    <xsl:variable name="root" select="$inputRoot"/> 
    rest of your code goes here... 
이제

, 모든 루트를 교체 $ root/blah/blah/blah로 액세스하면 수정 된 XSL 데이터가 사용됩니다!

멋진 점은 입력 데이터를 전달하지 않으면 입력이 루트라고 가정합니다! ;)

이것은 테스트되었고 완벽하게 작동합니다. XSL 입력이 거대하면 전체 루트를 재구성하면 성능 문제가 발생할 수 있습니다. 하지만 필자의 의견은 겨우 두세 가지 기록이었고 내 경우에는 성능에 전혀 영향을주지 않았습니다.

입력 데이터가 큰지 다시 한번 확인하십시오.

이 솔루션/방법은 XSL 1.0 친화적 인 방법입니다.

+0

내가하는 일을하는 것처럼 들리지만 내 대답은 소스 XML을 업스트림으로 마사지하여 helloworld 템플릿에 전달했다는 것입니다. 미안하지만이 내용을 명확하게하지 않았습니다. 다행스럽게 생각해 냈습니다! – LarsH

1

아니요, XSL에서는 소스 문서를 현재 위치에서 수정할 수 없습니다.

그러나 소스 문서를 별도의 XSL 스타일 시트를 사용하여 마사지 한 다음 원본 문서를 처리하는 대신 "hello-world"템플릿을 호출하는 XSL 스타일 시트에 마사지 된 문서를 전달할 수 있습니다.

스타일 시트를 수정할 수있는 경우 "hello-world"가 포함 된 동일한 스타일 시트에서이 작업을 수행 할 수도 있습니다. (하지만 스타일 시트를 수정할 수 없거나 "hello-world"를 수정할 수는 없을 것입니다.)

+0

감사합니다 LarsH,/사본을 만들 수 있지만 수정 된 레코드로 대체 할 수 있습니까? – codenamezero

+0

@codenamezero : 가능합니다. 사본 *의 레코드 *가 대체된다는 의미 일 경우 가능합니다. 템플릿의 결과가 결과 트리 조각이므로 XSLT 1.0을 사용해야하는 경우 조금 더 어렵습니다. hello-world 템플릿에서 사용할 노드 집합으로 되돌리려면 node-set() 확장 함수가 필요합니다. . (http://www.xml.com/pub/a/2003/07/16/nodeset.html 참조) – LarsH

+0

나는 그것을 조사 할 것이다. 마침내 레코드를 걸러 내고 데이터를 필터링/데이터로 대체 할 수 있었지만 현재이 새로운 데이터를 "hello-world"템플릿에 전달하는 데 어려움을 겪고 있습니다. 아침 내내 대답을 찾고 있었고 네가 도착했다. 수정 한 기존 입력을 노드 집합으로 설정할 수 있습니까? (원래의 스레드를 실험 한 새로운 코드로 업데이트했습니다.) – codenamezero

관련 문제