2009-06-10 8 views
0

SSIS 패키지 XML 작업 내에서 XML 파일에 XSL 변환을 적용하려고합니다.SSIS의 XML 작업에서 exsl 함수 node-set() 사용/구현

불행히도 내 XSL은 정상적인 것보다 약간 "이동성이 떨어짐"이며, node-set() 함수를 사용해야합니다. 내 XSL의 간단한 예는 다음과 같습니다

<xsl:for-each select="msxsl:node-set($familyNames)/token"> 
    <xsl:call-template name="PersonNameComponent"> 
    <xsl:with-param name="nameComponentType" select="'S'" /> 
    <xsl:with-param name="nameComponentSeqNo" select="number($noOfGivenNames) + position()" /> 
    <xsl:with-param name="nameComponent" select="." /> 
    <xsl:with-param name="nameTypeName" select="$familyName" /> 
    <xsl:with-param name="roleCode" select="$roleCode" /> 
    </xsl:call-template> 
</xsl:for-each> 

나는 스타일 시트 선언에 다음 네임 스페이스를 사용하고 있습니다 : 나는 XSLT를 설정 한대로이만큼 VS IDE, XMLSPY (작동

xmlns:msxsl="urn:schemas-microsoft-com:xslt" 

MSXML 같은 엔진) 등 그러나, 나는 다음과 같은 예외가 패키지 내에서 XML 작업을 실행하려고 할 때 :

Error: 0xC002F304 at XML Task, XML Task: An error occurred with the following error message: "Function 'msxsl:node-set()' has failed.".

나는 그것이 SSIS의 2005 년 버전의로 패키지를 디자인하는 VS2005를 사용하고 있습니다.

내가 어떻게 진행할 수 있는지에 대한 아이디어는 매우 높이 평가됩니다.

EXSLT str : split 함수를 구현하는 템플릿을 호출하여 구성 요소에 문자열을 "토큰 화"합니다.

<token>Kermit</token> 
<token>T</token> 
<token>Frog</token> 

이 내가 다음을 통해 반복 변수 $ familyNames에 저장되어 다음과 같이 "커밋 T 개구리"반환됩니다. 그러나 이것은 결과 트리 조각으로 반환되므로 결과를 노드 집합으로 처리하도록 msxsl : node-set() 함수로 래핑해야합니다. 확실하지 어떻게 내가 위의 달성 할 수 있습니다. 여기

는 STR의 구현입니다 :

<xsl:template name="str:split"> 
    <xsl:param name="string" select="''" /> 
    <xsl:param name="pattern" select="' '" /> 
    <xsl:choose> 
    <xsl:when test="not($string)" /> 
    <xsl:when test="not($pattern)"> 
     <xsl:call-template name="str:_split-characters"> 
     <xsl:with-param name="string" select="$string" /> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:call-template name="str:_split-pattern"> 
     <xsl:with-param name="string" select="$string" /> 
     <xsl:with-param name="pattern" select="$pattern" /> 
     </xsl:call-template> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
<xsl:template name="str:_split-characters"> 
    <xsl:param name="string" /> 
    <xsl:if test="$string"> 
    <token><xsl:value-of select="substring($string, 1, 1)" /></token> 
    <xsl:call-template name="str:_split-characters"> 
     <xsl:with-param name="string" select="substring($string, 2)" /> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 
<xsl:template name="str:_split-pattern"> 
    <xsl:param name="string" /> 
    <xsl:param name="pattern" /> 
    <xsl:choose> 
    <xsl:when test="contains($string, $pattern)"> 
     <xsl:if test="not(starts-with($string, $pattern))"> 
     <token><xsl:value-of select="substring-before($string, $pattern)" /></token> 
     </xsl:if> 
     <xsl:call-template name="str:_split-pattern"> 
     <xsl:with-param name="string" select="substring-after($string, $pattern)" /> 
     <xsl:with-param name="pattern" select="$pattern" /> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <token><xsl:value-of select="$string" /></token> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
+0

$ familyNames의 출처는 어디입니까? XSLT를 생성하는 부분을 게시 할 수 있습니까? 어쩌면 node-set()을 피할 수있는 방법이있을 수 있습니다. – Tomalak

+0

수정 된 질문은 요청한대로 문제를 자세히 설명합니다. – pFrenchie

답변

3

나는 XML을 변환하는 사용자 정의 스크립트 작업 대신 XML 태스크를 사용하여 포함하는 주변 일에 왔어요 : 나는 http://www.exslt.org/에서 얻은 분할 . 스크립트 작업의 코드는 다음과 같습니다

Imports System 
Imports Microsoft.SqlServer.Dts.Runtime 
Imports Mvp.Xml.Common.Xsl 

Public Class ScriptMain 

    ' The execution engine calls this method when the task executes. 
    ' To access the object model, use the Dts object. Connections, variables, events, 
    ' and logging features are available as static members of the Dts class. 
    ' Before returning from this method, set the value of Dts.TaskResult to indicate success or failure. 
    ' 
    ' To open Code and Text Editor Help, press F1. 
    ' To open Object Browser, press Ctrl+Alt+J. 

    Public Sub Main() 

     Dts.TaskResult = Dts.Results.Failure 

     If Dts.Variables.Contains("FullSourcePathFileName") AndAlso _ 
      Dts.Variables.Contains("XsltPath") AndAlso _ 
      Dts.Variables.Contains("FullSourceTransformedPathFileName") Then 

      Dim input As String = CType(Dts.Variables("FullSourcePathFileName").Value, String) 
      Dim xsl As String = CType(Dts.Variables("XsltPath").Value, String) 
      Dim output As String = CType(Dts.Variables("FullSourceTransformedPathFileName").Value, String) 

      Try 
       Dim xslt As New MvpXslTransform() 
       xslt.Load(xsl) 
       xslt.Transform(New XmlInput(input), Nothing, New XmlOutput(output)) 

       Dts.TaskResult = Dts.Results.Success 
      Catch ex As Exception 
       Throw 
       ' Look at logging, e.g. Dts.Logging.Log() 
      End Try 
     End If 

    End Sub 

End Class 

나는 EXSLT 기능의 .NET 구현을 제공 조립 (코드 플렉스에서 사용 가능) Mvp.Xml 프로젝트를 참조하고 있습니다. 보너스 부작용으로 이것은 str : split 템플릿 구현을 xsl에서 제거 할 수 있음을 의미합니다. 나는 다음과 같은 사용하여 Microsoft MSXML 네임 스페이스 선언을 교체했습니다 직접 분할 기능 (변수에 저장할 필요가 없습니다) :

xmlns:exsl="http://exslt.org/common" 

는 str을 호출합니다.

내가 알고있는 유일한 의미는 SSIS를 설치할 서버의 GAC에 Mvp.Xml을 설치해야한다는 것입니다 (자세한 내용은 here 참조).