XSLT для выравнивания определенных узлов XML - PullRequest
0 голосов
/ 14 октября 2011

Я получаю XML в формате, указанном ниже. Я пишу некоторый код для преобразования XML таким образом, что будут сглаживаться только определенные узлы.

<TransactionRequest>
  <OrderRequests>
    <OrderRequest>
      <ReferenceNumber>1234567</ReferenceNumber>
      <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime>
      <IsRush>true</IsRush>
      <ShippingAddress>
        <Name>Tom Hanks</Name>
        <Address1>1123 Canada Way</Address1>
        <City>Burnaby</City>
        <Province>BC</Province>
        <PostalCode>V3B13B</PostalCode>
        <HomePhone>6048871121</HomePhone>
        <BusinessPhone>6041232342</BusinessPhone>
      </ShippingAddress>
      <ProgramType>C2</ProgramType>
      <Comments>Deliver to the receptionist</Comments>
      <Items>
        <Item>
          <Sku>UN10004</Sku>
          <Quantity>2</Quantity>
        </Item>
        <Item>
          <Sku>UN980011</Sku>
          <Quantity>1</Quantity>
        </Item>
      </Items>
    </OrderRequest>
  </OrderRequests>
  <TraceRequests>
    <TraceRequest>
      <ReferenceNumber>23432345</ReferenceNumber>
      <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime>
      <OriginalReferenceNumber>1234567</OriginalReferenceNumber>
      <Comments>Trace Items</Comments>
      <TraceItems>
        <TraceItem>
          <Sku>UN10004</Sku>
          <Quantity>2</Quantity>
          <ShipmentNumber>CM88888990</ShipmentNumber>
        </TraceItem>
        <TraceItem>
          <Sku>UN980011</Sku>
          <ProductCode>AA0091</ProductCode>
          <Quantity>1</Quantity>
          <ShipmentNumber>DDP123123123</ShipmentNumber>
        </TraceItem>
      </TraceItems>
    </TraceRequest>
  </TraceRequests>
</TransactionRequest>

Я бы хотел, чтобы результат выглядел как следующий XML. Разница заключается в том, что в этом XML узлы TraceRequest будут разделены по одному на каждый узел Предметов / Предметов путем дублирования родительской информации один раз для каждого Предмета / Предмета.

<?xml version="1.0"?>
<TransactionRequest>
  <OrderRequests>
    <OrderRequest>
      <ReferenceNumber>1234567</ReferenceNumber>
      <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime>
      <IsRush>true</IsRush>
      <ShippingAddress>
        <Name>Tom Hanks</Name>
        <Address1>1123 Canada Way</Address1>
        <City>Burnaby</City>
        <Province>BC</Province>
        <PostalCode>V3B13B</PostalCode>
        <HomePhone>6048871121</HomePhone>
        <BusinessPhone>6041232342</BusinessPhone>
      </ShippingAddress>
      <ProgramType>C2</ProgramType>
      <Comments>Deliver to the receptionist</Comments>
      <Items>
        <Item>
          <Sku>UN10004</Sku>
          <Quantity>2</Quantity>
        </Item>
        <Item>
          <Sku>UN980011</Sku>
          <Quantity>1</Quantity>
        </Item>
      </Items>
    </OrderRequest>
  </OrderRequests>
  <TraceRequests>
    <TraceRequest>
      <ReferenceNumber>23432345</ReferenceNumber>
      <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime>
      <OriginalReferenceNumber>1234567</OriginalReferenceNumber>
      <Comments>Trace Items</Comments>
      <Sku>UN10004</Sku>
      <Quantity>2</Quantity>
      <ShipmentNumber>CM88888990</ShipmentNumber>
    </TraceRequest>
    <TraceRequest>
      <ReferenceNumber>23432345</ReferenceNumber>
      <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime>
      <OriginalReferenceNumber>1234567</OriginalReferenceNumber>
      <Comments>Trace Items</Comments>
      <Sku>UN980011</Sku>
      <ProductCode>AA0091</ProductCode>
      <Quantity>1</Quantity>
      <ShipmentNumber>DDP123123123</ShipmentNumber>
    </TraceRequest>
  </TraceRequests>
</TransactionRequest>

Кажется, я не могу сгенерировать XSLT, чтобы сгладить только определенные элементы подузлов элемента TraceRequest.

Ответы [ 2 ]

2 голосов
/ 14 октября 2011

Вы можете сделать это, переопределив стандартное преобразование идентичности дополнительными шаблонами для особых случаев.

Во-первых, когда вы соответствуете узлу TraceRequest , вы хотите сразу перейти к соответствующим узлам TraceItem , где вы будете выполнять копирование. В этом случае текущий узел TraceRequest может быть передан в качестве параметра для последующего копирования его детей.

<xsl:template match="TraceRequest">
   <xsl:apply-templates select="TraceItems/TraceItem">
      <xsl:with-param name="TraceRequestNode" select="."/>
   </xsl:apply-templates>
</xsl:template>

Затем при сопоставлении TraceItem можно просто скопировать дочерние элементы TraceRequest , переданные через параметр (исключая узел TraceItems ), а также дочерние элементы узла TraceItem , на котором вы сейчас находитесь.

<xsl:template match="TraceItem">
   <xsl:param name="TraceRequestNode"/>
   <TraceRequest>
      <xsl:apply-templates select="$TraceRequestNode/*[not(self::TraceItems)]"/>
      <xsl:apply-templates select="@*|node()"/>
   </TraceRequest>
</xsl:template>

Итак, учитывая полный XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes" />

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

   <xsl:template match="TraceRequest">
      <xsl:apply-templates select="TraceItems/TraceItem">
         <xsl:with-param name="TraceRequestNode" select="."/>
      </xsl:apply-templates>
   </xsl:template>

   <xsl:template match="TraceItem">
      <xsl:param name="TraceRequestNode"/>
      <TraceRequest>
         <xsl:apply-templates select="$TraceRequestNode/*[not(self::TraceItems)]"/>
         <xsl:apply-templates select="@*|node()"/>
      </TraceRequest>
   </xsl:template>
</xsl:stylesheet>

При применении к вашему образцу XML вывод будет следующим:

<TransactionRequest>
   <OrderRequests>
      <OrderRequest>
         <ReferenceNumber>1234567</ReferenceNumber>
         <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime>
         <IsRush>true</IsRush>
         <ShippingAddress>
            <Name>Tom Hanks</Name>
            <Address1>1123 Canada Way</Address1>
            <City>Burnaby</City>
            <Province>BC</Province>
            <PostalCode>V3B13B</PostalCode>
            <HomePhone>6048871121</HomePhone>
            <BusinessPhone>6041232342</BusinessPhone>
         </ShippingAddress>
         <ProgramType>C2</ProgramType>
         <Comments>Deliver to the receptionist</Comments>
         <Items>
            <Item>
               <Sku>UN10004</Sku>
               <Quantity>2</Quantity>
            </Item>
            <Item>
               <Sku>UN980011</Sku>
               <Quantity>1</Quantity>
            </Item>
         </Items>
      </OrderRequest>
   </OrderRequests>
   <TraceRequests>
      <TraceRequest>
         <ReferenceNumber>23432345</ReferenceNumber>
         <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime>
         <OriginalReferenceNumber>1234567</OriginalReferenceNumber>
         <Comments>Trace Items</Comments>
         <Sku>UN10004</Sku>
         <Quantity>2</Quantity>
         <ShipmentNumber>CM88888990</ShipmentNumber>
      </TraceRequest>
      <TraceRequest>
         <ReferenceNumber>23432345</ReferenceNumber>
         <TransactionTime>2010-11-16T00:00:00-08:00</TransactionTime>
         <OriginalReferenceNumber>1234567</OriginalReferenceNumber>
         <Comments>Trace Items</Comments>
         <Sku>UN980011</Sku>
         <ProductCode>AA0091</ProductCode>
         <Quantity>1</Quantity>
         <ShipmentNumber>DDP123123123</ShipmentNumber>
      </TraceRequest>
   </TraceRequests>
</TransactionRequest>
0 голосов
/ 14 октября 2011

Хорошо, я думаю, что ответил на свой собственный вопрос, используя XSLT ниже:

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

  <xsl:template match="TransactionRequest">
    <TransactionRequest>
      <xsl:copy-of select="OrderRequests"/>
      <TraceRequests>
        <xsl:for-each select="TraceRequests/TraceRequest/TraceItems/TraceItem">
          <TraceRequest>
            <xsl:copy-of select="../../ReferenceNumber"/>
            <xsl:copy-of select="../../TransactionTime"/>
            <xsl:copy-of select="../../OriginalReferenceNumber"/>
            <xsl:copy-of select="../../Comments"/>

            <xsl:copy-of select="Sku"/>
            <xsl:copy-of select="Quantity"/>
            <xsl:copy-of select="ShipmentNumber"/>
            <xsl:copy-of select="ProductCode"/>
            <xsl:copy-of select="DropShipPoNumber"/>
          </TraceRequest>
        </xsl:for-each>
      </TraceRequests>
   </TransactionRequest>
  </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...