извлеките каждый дочерний узел для создания XML с родительскими узлами

#xml #xslt #biztalk

#xml #xslt #biztalk

Вопрос:

У меня есть входной XML, подобный follwing. Мне нужно извлечь каждый дочерний <DETS> узел и создать новый XML, объединив его с его общими родительскими узлами.

Ввод:

 <STDS>
    <DEPT>ABC</DEPT>
    <COD>123</COD>
    <PIN>456</PIN>
    <DETS>
        <NAM>XYZ</NAM>
        <AGE>21</AGE>
    </DETS>
    <DETS>
        <NAM>KLM</NAM>
        <AGE>22</AGE>
    </DETS>
</STDS>

I need the output like following.
  

Вывод:

 <Students>
    <Department>ABC</Department>
    <Code>123</Code>
    <Pin>456</Pin>
    <Details>
        <Name>XYZ</Name>
        <Age>21</Age>
    </Details>
</Students>
<Students>
    <Department>ABC</Department>
    <Code>123</Code>
    <Pin>456</Pin>
    <Details>
        <Name>KLM</Name>
        <Age>22</Age>
    </Details>
</Students>
  

Я пробовал использовать for-each, но не могу.

вот код, который я пытаюсь. Если я сохраню for-each внутри <students> , он создаст новый XML для каждого дочернего элемента внутри <students> . если я использую для каждого XML снаружи, как можно получить доступ к элементам <Students> вне области видимости.

 <?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var" exclude-result-prefixes="msxsl var s0 userCSharp" version="1.0" xmlns:ns0="Students" xmlns:s0="STDS" xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp">
  <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
  <xsl:template match="/">
    <xsl:apply-templates select="/s0:STDS" />
  </xsl:template>
<xsl:template match="/s0:STDS">
    <ns0:Students>
        <xsl:for-each select="s0:STDS">
            <xsl:variable name="var:v1" select="s0:DEPT" />
            <Department>
            <xsl:value-of select="$var:v1" />
            </Department>
            <xsl:variable name="var:v2" select="s0:COD" />
            <Code>
            <xsl:value-of select="$var:v2" />
            </Code>
            <xsl:variable name="var:v3" select="s0:PIN)" />
            <Pin>
            <xsl:value-of select="$var:v3" />
            </Pin>

            <xsl:for-each select="s0:STDS/s0:DETS">
                <ns0:Details>
                <xsl:variable name="var:v4" select="s0:DETS/s0:NAM" />
                <Name>
                <xsl:value-of select="$var:v4" />
                </Name>
                <xsl:variable name="var:v5" select="s0:DETS/s0:AGE" />
                <Age>
                <xsl:value-of select="$var:v5" />
                </Age>
                <ns0:Details>
            </xsl:for-each>
        </xsl:for-each>
    <ns0:Students>
  </xsl:template>
  

Комментарии:

1. Пожалуйста, отредактируйте вопрос и поделитесь проверенным XSL, чтобы его можно было изменить. Выходной XML показывает, что вы также переименовываете все узлы на новые имена из входного XML.

2. Я добавил код.

3. Почему вы хотите использовать Xsl? Это можно сделать только с одним функциональным идентификатором в Map.

Ответ №1:

Эта ../ функция может использоваться для перехода по уровням XML из дочернего контекста в родительский контекст.

Ниже приведен шаблон XSL, который вы можете использовать. Пожалуйста, обратите внимание, что общий входной XML-файл не имеет объявленных пространств имен, следовательно, в приведенном ниже решении нет ссылок на пространства имен. Это должно дать вам желаемый результат.

 <xsl:template match="/">
    <xsl:for-each select="STDS/DETS">
        <Students>
            <Department><xsl:value-of select="../DEPT" /></Department>
            <Code><xsl:value-of select="../COD" /></Code>
            <Pin><xsl:value-of select="../PIN" /></Pin>
            <Details>
                <Name><xsl:value-of select="NAM" /></Name>
                <Age><xsl:value-of select="AGE" /></Age>
            </Details>
        </Students>
    </xsl:for-each>
</xsl:template>
  

Комментарии:

1. Для удобства будущих читателей вам не нужен пользовательский Xslt для этого в BizTalk . Это просто добавляет ненужных сложностей.

Ответ №2:

Вопрос помечен как BizTalk. Это правильный ответ BizTalk.

В Mapper все, что вам нужно сделать, это подключиться <DETS> к <Students> нему через циклический функтоид.

Вот и все, пользовательский xslt не требуется. Да, это так просто.

__

Невозможно отредактировать ответ, поскольку это один и тот же ответ на два разных вопроса. Это специфическая ситуация для BizTalk. Вопрос помечен как BizTalk. Хотя они могут быть технически правильными, ответы Xsl не являются правильным способом сделать это в BizTalk.

Удаление этого ответа просто удаляет правильный ответ, специфичный для домена BizTalk. Если этот ответ снова будет удален, хорошо, я просто сдамся, и OP может бороться с излишне сложным и неправильным (для BizTalk) решением.