2009-06-10 2 views
0

Я пытаюсь применить преобразование XSL к XML-файлу в XML-задаче пакета SSIS.Использование/реализация функции exsl node-set() в XML-задаче SSIS

Все хорошо и хорошо, но, к сожалению, мой 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> 

Я использую следующие пространства имен в объявлении таблицы стилей:

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

Это работает в VS IDE, XMLSpy (до тех пор, как я установил XSLT двигатель, как MSXML) и т.д. Тем не менее, при попытке выполнить задачу XML в пакете я получаю следующее исключение:

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

Я использую VS2005 для разработки пакета, как это версия SSIS 2005.

Любые идеи о том, как я могу продолжить, очень ценятся.

Я вызываю шаблон, который реализует функцию EXSLT str: split для «tokenise» строки в ее составные элементы, например. «Кермит T Frog» будет возвращено следующим образом:

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

Это хранится в переменной $ familyNames, которые я потом перебирать. Однако, поскольку это возвращается как фрагмент дерева результатов, мне нужно обернуть его с помощью функции msxsl: node-set(), чтобы результат обрабатывался как набор узлов. Не знаю, как еще я могу достичь вышеизложенного.

Вот реализация ул: расколоть, что я получил от http://www.exslt.org/:

<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, которая ее создает? Возможно, есть способ избежать набора узлов() вообще. – Tomalak

+0

Отредактированный вопрос для дальнейшей разработки проблемы по запросу. – pFrenchie

ответ

3

Я пришел с работы вокруг, что предполагает использование пользовательских задач сценария вместо задачи XML для преобразования XML , Код в задаче сценария является:

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 

Я ссылающийся на проект Mvp.Xml (доступный на CodePlex) сборки, которая обеспечивает реализацию .NET функций EXSLT. В качестве бонусного побочного эффекта это означает, что я могу удалить реализацию шаблона str: split из xsl. Я заменил декларацию MSXML пространства имен Microsoft со следующим:

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

назвать ул: функция разделения напрямую (нет необходимости хранить его в переменной).

Единственное, что я знаю, это то, что мне нужно установить Mvp.Xml в GAC сервера, на котором будет установлен SSIS (подробности см. В разделе here).

Смежные вопросы