Сортировка подсущностей в сложном XML в BizTalk

Я получаю некоторые данные из WebService, которые выглядят так

Building
     Address
     -> Office
         Name
         CreationDate
         -> Worker
              Name
              HiringDate 

Прежде чем выполнять дальнейшую обработку и преобразование этого сообщения, мне нужно отсортировать подузлы («Офис» и «Рабочий»), чтобы все офисы были отсортированы по CreationDate, а затем все рабочие отсортированы по HiringDate внутри своего офиса.

До сих пор единственными решениями для сортировки в BizTalk, которые я видел, были основаны на XSLT. Есть несколько примеров, демонстрирующих более простую структуру сортировки (http://www.biztalkgurus.com/newsletter/TheBizTalker-Volume-03.html), но они не будут работать как есть, поскольку мое сообщение имеет несколько уровней.

Если вы понятия не имеете, как (если это вообще возможно) написать выражение XSLT, которое будет выполнять эту сортировку, сохраняя при этом структуру XML.

Можно ли написать такое выражение XSLT? Как бы это выглядело?


person TheOwlsAreNotWhatTheySeem    schedule 29.10.2010    source источник
comment
Пожалуйста, опубликуйте небольшой XML-документ и желаемый результат XML.   -  person Dimitre Novatchev    schedule 29.10.2010


Ответы (2)


Решение найдено здесь: http://bloggingabout.net/blogs/wellink/archive/2005/12/09/10499.aspx

Если мы применим эту технику к нашему примеру, мы получим этот XSLT

    <xsl:for-each select="Office">
        <xsl:sort select="CreationDate" data-type="text" order="ascending"/>        
        <Office>
            <xsl:copy-of select="Name"/>
            <xsl:copy-of select="CreationDate"/>
            <xsl:for-each select="Worker">
                <xsl:sort select="HiringDate" data-type="text" order="ascending"/>
                <Worker>
                    <xsl:copy-of select="Name"/>
                    <xsl:copy-of select="HiringDate"/>
                </Worker>
            </xsl:for-each>
        </Office>
    </xsl:for-each>

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

person TheOwlsAreNotWhatTheySeem    schedule 02.11.2010

Вам нужны шаблоны XSLT-копий для всех тегов, кроме Office и Worker, а также шаблоны сортировки для этих тегов. например Копировать шаблоны:

<xsl:template match="node()">
    <xsl:if test="name()">
        <xsl:element name="{name()}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:if>
</xsl:template>

<xsl:template match="text()">
    <xsl:value-of select="."/>
</xsl:template>

<xsl:template match="@*">
    <xsl:copy>
        <xsl:value-of select="."/>
    </xsl:copy>
</xsl:template>

И шаблоны сортировки:

<xsl:match="office_parent_tag_as_i_understand_Building">
    <xsl:apply-templates select="Office">
        <xsl:sort select="CreationDate" data-type="text" order="ascending"/>
    </xsl:foreach>
</xsl:template>

и аналог рабочего тега

<xsl:match="worker_parent_tag_as_i_understand_Office">
    <xsl:apply-templates select="Worker">
        <xsl:sort select="HiringDate" data-type="text" order="ascending"/>
    </xsl:foreach>
</xsl:template>

Не забывайте, что xsl:sort работает только с числовыми и текстовыми данными, для сортировки по дате нужно преобразовать дату в int или строку

person seriyPS    schedule 29.10.2010
comment
Я не уверен, как бы вы вводили весь этот XSLT внутри biztalk (он имеет только одно окно сценария для встроенного XSLT и, кажется, не принимает объект шаблона внутри него). И как в этом случае вы подключаете вывод к правой стороне схемы? - person TheOwlsAreNotWhatTheySeem; 02.11.2010