XSLT для каждого цикла с динамическими фильтрами - PullRequest
0 голосов
/ 27 сентября 2019

Это упрощенная версия XML-сообщения (SAP-IDOC), которую мне нужно преобразовать в более легкий для чтения XML, как показано в примере ниже.

Это IDOC доставки SAP, которая дает мнеинформация для отгрузки и ее позиции.Проблема в том, что позиции 10 и 20 могут быть в одной коробке (E1EDL37) и иметь другой номер для отслеживания (поле TRACKN), чем позиция 3.

<DELVRY07>
<IDOC>
    <E1EDL20> <!-- Contains all positions-->
        <E1EDL24> <!--one Node for each position -->
            <POSNR>000010</POSNR>
            <MATNR>123</MATNR>
            <E1EDL41>
                <BSTNR>Fall 1</BSTNR>
            </E1EDL41>
        </E1EDL24>
        <E1EDL24><!--one Node for each position -->
            <POSNR>000020</POSNR>
            <MATNR>456</MATNR>
            <E1EDL41>
                <BSTNR>Fall 2</BSTNR>
            </E1EDL41>
        </E1EDL24>
        <E1EDL24><!--one Node for each position -->
            <POSNR>000030</POSNR>
            <MATNR>789</MATNR>
            <E1EDL41>
                <BSTNR>Fall 3</BSTNR>
            </E1EDL41>
        </E1EDL24>
        <E1EDL37><!--one Node for every carton-->
            <E1EDL49>
                <XSITD>UPS1</XSITD>
                <TRACKN>Track 1</TRACKN>
            </E1EDL49>
            <E1EDL44><!-- every position in the carton-->
                <VBELN>123456</VBELN>
                <POSNR>000010</POSNR>
            </E1EDL44>
            <E1EDL44><!-- every position in the carton-->
                <VBELN>456789</VBELN>
                <POSNR>000020</POSNR>
            </E1EDL44>
        </E1EDL37>
        <E1EDL37><!--one Node for every carton-->
            <E1EDL49>
                <XSITD>DPD</XSITD>
                <TRACKN>Track 2</TRACKN>
            </E1EDL49>
            <E1EDL44><!-- every position in the carton-->
                <VBELN>123456</VBELN>
                <POSNR>000030</POSNR>
            </E1EDL44>
        </E1EDL37>
    </E1EDL20>
</IDOC>

это должно быть сообщение xml после преобразования xslt (или схожее сообщение):

<Shipment>
    <Positions>
        <POSNR>000010</POSNR>
        <MATNR>123</MATNR>
        <BSTNR>Fall 1</BSTNR>
        <TRACKN>Track 1</TRACKN>
        <XSITD>UPS1</XSITD>
    </Positions>
    <Positions>
        <POSNR>000020</POSNR>
        <MATNR>456</MATNR>
        <BSTNR>Fall 2</BSTNR>
        <TRACKN>Track 1</TRACKN>
        <XSITD>UPS1</XSITD>
    </Positions>
    <Positions>
        <POSNR>000030</POSNR>
        <MATNR>123</MATNR>
        <BSTNR>Fall 3</BSTNR>
        <TRACKN>Track 2</TRACKN>
        <XSITD>DPD</XSITD>
    </Positions>
</Shipment>

Я попытался пройти элементы E1EDL24 с помощью цикла и записать информацию в переменные.Но с этого момента мне нужно будет выполнить цикл по всему E1EDL44 и получить значение поля TRACKN элемента E1EDL49 выше.

Не могли бы вы помочь мне найти способ сделать это?

Большое спасибо за вашу помощь!

Ответы [ 2 ]

1 голос
/ 27 сентября 2019

Если я правильно следую этому (что совсем не точно), вы хотите создать запись для каждой «позиции» и извлечь дополнительные данные из соответствующей «коробки»:

XSLT1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="carton-by-position" match="E1EDL37" use="E1EDL44/POSNR" />

<xsl:template match="/DELVRY07">
    <Shipment>
        <xsl:for-each select="IDOC/E1EDL20/E1EDL24">
            <Positions>
                <xsl:copy-of select="POSNR | MATNR | E1EDL41/BSTNR"/>
                <xsl:copy-of select="key('carton-by-position', POSNR)/E1EDL49/*"/>
            </Positions>
        </xsl:for-each>
    </Shipment>
</xsl:template>

</xsl:stylesheet>
0 голосов
/ 27 сентября 2019

Попробуйте этот шаблон:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/IDOC/E1EDL20">
    <xsl:variable name="parent" select="."/>
    <Shipment>
      <xsl:for-each select="E1EDL24/POSNR">
        <xsl:variable name="posnr" select="."/>
        <Position>
          <POSNR><xsl:value-of select="$posnr"/></POSNR>
          <MATNR><xsl:value-of select="../MATNR"/></MATNR>
          <BSTNR><xsl:value-of select="../E1EDL41/BSTNR"/></BSTNR>
          <TRACKN><xsl:value-of select="$parent/E1EDL37[E1EDL44/POSNR=$posnr]/E1EDL49/TRACKN"/></TRACKN>
          <XSITD><xsl:value-of select="$parent/E1EDL37[E1EDL44/POSNR=$posnr]/E1EDL49/XSITD"/></XSITD>
        </Position>
      </xsl:for-each>
    </Shipment>
    </xsl:template>

</xsl:stylesheet>

Онлайн-скрипка здесь

...