동일한 노드에서 구성이 다른 일치하는 템플릿

Nov 23 2020

나는 스택 오버플로에 대한 내 전체 질문을 여기에 물었다 .

이 소스에서 XML을 만들어야합니다. 아주 간단히 :

    <?xml version="1.0" encoding="UTF-8"?>
    <FMPDSORESULT xmlns="http://www.filemaker.com/fmpdsoresult">
        <ROW>
        <EDI_DC40.TABNAM><DATA>EDI_DC40</DATA></EDI_DC40.TABNAM>
        <E1EDL20.VBELN><DATA>649758</DATA></E1EDL20.VBELN>
        <E1EDL18.QUALF><DATA>ORI</DATA></E1EDL18.QUALF>
        <E1EDT13.1.QUALF><DATA>007<DATA></E1EDT13.1.QUALF>
        <E1EDT13.2.QUALF><DATA>015</DATA></E1EDT13.2.QUALF>
        <E1EDL24.POSNR>000001</E1EDL24.POSNR>
        <E1EDL24.POSNR>2</E1EDL24.POSNR>
                (random number of these)
        <E1EDL41.QUALI>001</E1EDL41.QUALI>
        <E1EDL37.EXIDV><DATA>5650327422</DATA></E1EDL37.EXIDV>
        <E1EDL44.POSNR>000001</E1EDL44.POSNR> <!--(these are the line items, equal to the number of ROW)-->
    </ROW>
    <ROW>...

이것이 내가 필요한 것입니다.

    <DELVRY05>
        <IDOC BEGIN="1">
            <EDI_DC40 SEGMENT="1">
                <TABNAM>EDI-DC40</TABNAM>
            </EDI_DC40>
            <E1EDL20 SEGMENT="1">
                <VBELN>649758</VBELN>
                <E1EDL18 SEGMENT="1"><QUALF>ORI</QUALF></E1EDL18>
                <E1EDT13 SEGMENT="1"><QUALF>007</QUALF></E1EDT13>
                <E1EDT13 SEGMENT="1"><QUALF>015</QUALF></E1EDT13>
                <E1EDL24 SEGMENT="1">
                    <POSNR>000001</POSNR>
                    <E1EDL41 SEGMENT="1">
                        <QUALI>001</QUALI>
                    </E1EDL41>
                </E1EDL24>
                <E1EDL24 SEGMENT="1">
                    <POSNR>2</POSNR>
                    <E1EDL41 SEGMENT="1">
                         <QUALI>001</QUALI>
                    </E1EDL41>
                </E1EDL24>
                <E1EDL24 SEGMENT="1"> <!-- (random number of these, as commented above) -->
                    ...
                </E1EDL24>
            </E1EDL20>
        </IDOC>
    </DELVRY05>

이것은 내가 xsl에 대해 가진 아이디어입니다.

    <xsl:template match="/*">
        <DELVRY05>
            <IDOC BEGIN="1">
                <EDI_DC40 SEGMENT="1">
                    <xsl:apply-templates select="headers"/>
                </EDI_DC40>
                <E1EDL20 SEGMENT="1">
                    <xsl:apply-templates select="main"/>
                    <xsl:apply-templates select="fm:ROW"/>
                </E1EDL20>
            </IDOC>
        </DELVRY05>
    </xsl:template>

줄과 헤더가 모두 E1EDL20 태그에 포함되어 있기 때문에 두 개의 템플릿이 필요하고 둘 다 소스 코드에서 동일한 태그를 참조합니다. 사양에서 알 수 있듯이 마지막 템플릿 만 사용됩니다. (따라서 'header'와 'lines'는 표시되지만 'main'은 표시되지 않습니다.

    <xsl:template name="main" match="fm:ROW[1]"> ...

    <xsl:template name="headers" match="fm:ROW[1]"> ...

    <xsl:template name="lines" match="fm:ROW"> ...

이 문제를 어떻게 해결합니까?

편집하다:

@Sebastien : 귀하의 솔루션은 제가 처음에 제공 한 소스 코드에서 훌륭하게 작동했습니다. 훌륭한 대답입니다. 그러나 제가 제공 한 코드에 실수를하여 죄송합니다.

다음은 소스 코드의 형식입니다.

    <?xml version="1.0" encoding="UTF-8"?>
    <FMPDSORESULT xmlns="http://www.filemaker.com/fmpdsoresult">
        <ROW>
            <EDI_DC40.TABNAM><DATA>EDI_DC40</DATA></EDI_DC40.TABNAM>
            <E1EDL20.VBELN><DATA>649758</DATA></E1EDL20.VBELN>
            <E1EDL18.QUALF><DATA>ORI</DATA></E1EDL18.QUALF>
            <E1EDT13.1.QUALF><DATA>007</DATA></E1EDT13.1.QUALF>
            <E1EDT13.2.QUALF><DATA>015</DATA></E1EDT13.2.QUALF>
            <E1EDL24.POSNR>000001</E1EDL24.POSNR>
            <E1EDL41.QUALI>001</E1EDL41.QUALI>
            <E1EDL37.EXIDV><DATA>5650327422</DATA></E1EDL37.EXIDV>
            <E1EDL44.POSNR>000001</E1EDL44.POSNR>
        </ROW>
        <ROW>
            <EDI_DC40.TABNAM><DATA>EDI_DC40</DATA></EDI_DC40.TABNAM>
            <E1EDL20.VBELN><DATA>649758</DATA></E1EDL20.VBELN>
            <E1EDL18.QUALF><DATA>ORI</DATA></E1EDL18.QUALF>
            <E1EDT13.1.QUALF><DATA>007</DATA></E1EDT13.1.QUALF>
            <E1EDT13.2.QUALF><DATA>015</DATA></E1EDT13.2.QUALF>
            <E1EDL24.POSNR>2</E1EDL24.POSNR>
            <E1EDL41.QUALI>002</E1EDL41.QUALI>
            <E1EDL37.EXIDV><DATA>5650327422</DATA></E1EDL37.EXIDV>
            <E1EDL44.POSNR>000001</E1EDL44.POSNR>
        </ROW>
    </FMPDSORESULT>

문제는 헤더와 함께 하나의 태그가 있어야하지만 다음과 같이 광고 항목이 서로 아래에 나열되어야한다는 것입니다.

    <?xml version="1.0" encoding="utf-16"?>
    <DELVRY05>
      <IDOC BEGIN="1">
        <EDI_DC40 SEGMENT="1">
          <TABNAM>EDI_DC40</TABNAM>
        </EDI_DC40>
        <E1EDL20 SEGMENT="1">
          <VBELN>649758</VBELN>
          <E1EDL18 SEGMENT="1">
            <QUALF>ORI</QUALF>
          </E1EDL18>
          <E1EDL24 SEGMENT="1">
            <POSNR>000001</POSNR>
            <E1EDL41 SEGMENT="1">
              <QUALI>001</QUALI>
            </E1EDL41>
          </E1EDL24>
          <E1EDL24 SEGMENT="1">
            <POSNR>2</POSNR>
            <E1EDL41 SEGMENT="1">
              <QUALI>002</QUALI>
            </E1EDL41>
          </E1EDL24>
        </E1EDL20>
      </IDOC>
    </DELVRY05>

저와 함께 해주셔서 감사합니다. 대단히 감사합니다 !!

많은 의무가 있습니다, Tom

답변

Sebastien Nov 23 2020 at 16:38

시작하기위한 샘플이 있습니다. 귀하의 질문에는 몇 가지 규칙을 가정 한 일부 세부 정보가 없습니다.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fm="http://www.filemaker.com/fmpdsoresult"
    exclude-result-prefixes="fm"
    version="1.0">

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

  <xsl:template match="/">
    <DELVRY05>
      <xsl:apply-templates select="fm:FMPDSORESULT/fm:ROW[1]"/>
    </DELVRY05>
  </xsl:template>
  
  <xsl:template match="fm:ROW">
    <IDOC BEGIN="1">
      <EDI_DC40 SEGMENT="1">
        <TABNAM><xsl:value-of select="fm:EDI_DC40.TABNAM/fm:DATA"/></TABNAM>
      </EDI_DC40>
      <E1EDL20 SEGMENT="1">
        <VBELN><xsl:value-of select="fm:E1EDL20.VBELN/fm:DATA"/></VBELN>
        <E1EDL18 SEGMENT="1"><QUALF><xsl:value-of select="fm:E1EDL18.QUALF/fm:DATA"/></QUALF></E1EDL18>
        <!-- Same principle as above for E1EDT13.1, E1EDT1.2, etc. -->
        
        <!-- Use template for elements that are present mutltiple times. -->
        <xsl:apply-templates select="../fm:ROW/fm:E1EDL24.POSNR"/>
      </E1EDL20>
    </IDOC>
  </xsl:template>
  
  <xsl:template match="fm:E1EDL24.POSNR">
    <E1EDL24 SEGMENT="1">
      <POSNR><xsl:value-of select="."/></POSNR>
      <E1EDL41 SEGMENT="1">
        <QUALI><xsl:value-of select="../fm:E1EDL41.QUALI"/></QUALI>
      </E1EDL41>
    </E1EDL24>
  </xsl:template>
  
</xsl:stylesheet>

여기에서 작동하는 것을보십시오 : https://xsltfiddle.liberty-development.net/6q1SDka/1