XSL Transformation для динамического создания узлов XML - PullRequest
0 голосов
/ 18 мая 2018

Исходный XML:

<AWARD>
  <FIELD1>XYZ</FIELD1>
  <AWARDLINE>
     <ALINENUM>1</ALINENUM>
     <SHIPMENT>
        <SHIPLINENUM>1.1</SHIPLINENUM>
        <ACCOUNT>
          <ACCOUNTLINENUM>1.1.1</ACCOUNTLINENUM>
          <ASSOCIATEDREQ>
            <AREQNUM>1.1.1.1</AREQNUM>
          </ASSOCIATEDREQ>
        </ACCOUNT>
    </SHIPMENT>     
  </AWARDLINE>   
    <AWARDLINE>
     <ALINENUM>2</ALINENUM>
  </AWARDLINE>     
</AWARD>  

Кроме AWARD все дочерние узлы "AWARDLINE", "SHIPMENT", "ACCOUNT", "ASSOCIATEDREQ" могут существовать или не существовать.Как видно выше, AWARDLINE 2 не имеет узлов SHIPMENT / ACCOUNT / ASSOCIATEDREQ.

Желаемый целевой XML

<AWARD>
  <FIELD1>XYZ</FIELD1>
  <AWARDLINE>
     <ALINENUM>1</ALINENUM>
     <SHIPMENT>
        <SHIPLINENUM>1.1</SHIPLINENUM>
        <ACCOUNT>
          <ACCOUNTLINENUM>1.1.1</ACCOUNTLINENUM>
          <ASSOCIATEDREQ>
            <AREQNUM>1.1.1.1</AREQNUM>
          </ASSOCIATEDREQ>
        </ACCOUNT>
    </SHIPMENT>     
  </AWARDLINE>   
  <AWARDLINE>
     <ALINENUM>2</ALINENUM>
     <SHIPMENT> 
       <ACCOUNT>
         </ASSOCIATEDREQ>
       </ACCOUNT>
     </SHIPMENT>
  </AWARDLINE>     
</AWARD>

1 Ответ

0 голосов
/ 18 мая 2018

Вы можете использовать этот XSLT-1.0, который выполняет замену всех соответствующих узлов, если они присутствуют. Он избирательно восстанавливает структуру элемента AWARDLINE и работает в сочетании с шаблоном идентификации .

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- identity template -->
  <xsl:template match="node()|@*">
      <xsl:copy>
          <xsl:apply-templates select="node()|@*" />
      </xsl:copy>
  </xsl:template>

  <!-- reconstruction of the AWARDLINE element structure -->
  <xsl:template match="AWARDLINE">
    <xsl:copy>
        <xsl:copy-of select="*[not(self::SHIPMENT)]" />
        <SHIPMENT>
            <xsl:copy-of select="SHIPMENT/*[not(self::ACCOUNT)]" />
            <ACCOUNT>
                <xsl:copy-of select="SHIPMENT/ACCOUNT/*[not(self::ASSOCIATEDREQ)]" />
                <ASSOCIATEDREQ>
                    <xsl:copy-of select="SHIPMENT/ACCOUNT/ASSOCIATEDREQ/*" />
                </ASSOCIATEDREQ>
            </ACCOUNT>
        </SHIPMENT> 
    </xsl:copy>
  </xsl:template>    
</xsl:stylesheet>

Другая возможность - использование шаблонов. Это может обработать более одного SHIPMENT элемента и создать пустую структуру, если другие элементы отсутствуют.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- identity template -->
  <xsl:template match="node()|@*">
      <xsl:copy>
          <xsl:apply-templates select="node()|@*" />
      </xsl:copy>
  </xsl:template>

  <!-- reconstruction of the AWARDLINE element structure -->
  <xsl:template match="AWARDLINE">
    <xsl:copy>
        <xsl:copy-of select="*[not(self::SHIPMENT)]|@*" />
        <xsl:apply-templates select="SHIPMENT" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="AWARDLINE[not(SHIPMENT)]">
    <xsl:copy>
        <xsl:copy-of select="*|@*" />
        <SHIPMENT>
          <ACCOUNT>
            <ASSOCIATEDREQ />
          </ACCOUNT>
        </SHIPMENT>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="SHIPMENT">
    <xsl:copy>
        <xsl:copy-of select="*[not(self::ACCOUNT)]|@*" />
        <xsl:apply-templates select="ACCOUNT" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="SHIPMENT[not(ACCOUNT)]">  
    <xsl:copy>
        <xsl:copy-of select="*|@*" />
        <ACCOUNT>
          <ASSOCIATEDREQ />
        </ACCOUNT>
    </xsl:copy>   
  </xsl:template>  

  <xsl:template match="ACCOUNT">
    <xsl:copy>
        <xsl:copy-of select="*[not(self::ASSOCIATEDREQ)]|@*" />
        <xsl:apply-templates select="ASSOCIATEDREQ" />
    </xsl:copy>
  </xsl:template>  

  <xsl:template match="ACCOUNT[not(ASSOCIATEDREQ)]">  
    <xsl:copy>
        <xsl:copy-of select="*|@*" />
        <ASSOCIATEDREQ />
    </xsl:copy>   
  </xsl:template>  

  <xsl:template match="ASSOCIATEDREQ">
    <xsl:copy>
        <xsl:copy-of select="*|@*" />
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...