Создание переменного количества узлов в целевом документе без соответствующих данных в исходном документе - PullRequest
2 голосов
/ 21 сентября 2011

Я пытаюсь сопоставить два документа с BizTalk Mapper, и мой целевой документ должен выглядеть следующим образом:

<root>
  <complexType>
     <property>example</property>
  </complexType>
  <filler>
     <padding>9999999</padding>
  </filler>
  <filler>
     <padding>9999999</padding>
  </filler>
  <filler>
     <padding>9999999</padding>
  </filler>
</root>

Количество <filler> узлов, которые я должен создать, является переменным (от 0 до 9). В основном это результат расчета (на основе некоторых данных, представленных в исходном документе).

Есть ли способ создать эти <filler> узлы с некоторой комбинацией функтоидов?

Я попытался использовать функтоид Table Looping (создал таблицу только с одним столбцом, символ заполнения '9'), но на самом деле это не сработало, потому что он создает столько узлов <filler>, сколько строк определено в таблице, это не то, что я хочу, так как количество строк должно быть переменным (опять же, на основе расчета). Сейчас я передаю сообщение (XmlDocument) методу C #, а затем программно добавляю узлы <filler>. Я надеюсь, что есть более "BizTalk-y" способ сделать это с Mapper.

Ответы [ 2 ]

1 голос
/ 21 сентября 2011

Как указывалось, XSLT может создавать узлы на целевом документе по желанию (я не знал этого, и это была ключевая часть). Оказывается, мне нужен простой цикл for в XSLT. Как только я понял это, быстрый поиск в Google дал следующие результаты:

http://quomon.com/question-How-to-make-a-for-loop-in-xslt-not-for-each-809.aspx

http://snippets.dzone.com/posts/show/930

Еще одна вещь, на которую стоит обратить внимание, это то, что (как указано в первой ссылке) XSLT является функциональным языком, а не процедурным, поэтому иногда вам приходится прибегать к рекурсии или расширению. Этот случай определенно является одним из тех случаев, когда я не смог использовать тщательный выбор узлов, используя атрибут select в xsl: for-each (поскольку эти данные-заполнители не были частью исходного документа).

В частности, для этого случая я сделал следующее:

Добавьте функтоид Scripting. Добавьте два входа:

  • Константа со значением "1" (это начальное значение переменной i)
  • Длина цикла (количество повторений тела цикла)

Вставьте следующий шаблон XSLT в качестве сценария «Встроенный шаблон вызова XSLT»:

<xsl:template name="ForLoop"> 
<xsl:param name="i" />      <!-- index counter, 1-based, will be incremented with every recursive call -->
<xsl:param name="length" /> <!-- exit loop when i >= length -->

<!-- Output the desired node(s) if we're still looping -->
<!-- The base case is when i > length (in that case, do nothing) -->
<xsl:if test="$i &lt;= $length"> 
<Filler>
    <Padding>999999</Padding>
</Filler>
</xsl:if> 

<!-- Call the ForLoop template recursively, incrementing i -->
<xsl:if test="$i &lt;= $length"> 
<xsl:call-template name="ForLoop"> 
<xsl:with-param name="i"> 
<xsl:value-of select="$i + 1"/> 
</xsl:with-param> 
<xsl:with-param name="length"> 
<xsl:value-of select="$length"/> 
</xsl:with-param> 
</xsl:call-template> 
</xsl:if> 
</xsl:template>
1 голос
/ 21 сентября 2011

Я подозреваю, что вам придется решить эту проблему, изменив XSLT.

Добавьте некоторую логику, чтобы создать столько узлов-заполнителей, сколько требует ваш расчет - вы можете создать шаблон, который вы, возможно, вызовите в цикле, который добавит новый раздел-заполнитель.

Надеюсь, это направит вас в правильном направлении.

...