简体   繁体   中英

xslt grouping - convert from one xml format to other

I have an xslt written for transforming from one xml format to the other.

my source file has multiple "production orders" and one "Sales Order" my destination has only one "sales Order" which holds all production orders.

Here is my source xml format

 <GenomicOrder>
  <SalesOrder>
    ....
  </SalesOrder>
  <ProductionOrder>
    ....
  </ProductionOrder>
  <ProductionOrder>
    ....
  </ProductionOrder>
  <ProductionOrder>
    ....
  </ProductionOrder>
</GenomicOrder>

my destination xml format is as below

<GenomicOrder>
  <SalesOrder>
    ....
  <ProductionOrder>
    ....
  </ProductionOrder>
  <ProductionOrder>
    ....
  </ProductionOrder>
  <ProductionOrder>
    ....
  </ProductionOrder>
  </SalesOrder>
</GenomicOrder>

My deserialization code is as below

DataContractSerializer ser = new DataContractSerializer(typeof(SalesOrder));
            FileStream fs =
                new FileStream(
                    @"C:\realsample.xml",
                    FileMode.Open);
            XmlDictionaryReader reader1 = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());

            //Deserialize the data and read it from the instance.
            SalesOrder parent = (SalesOrder)ser.ReadObject(reader1, true);

            reader1.Close();

My successful sales order xslt Transformation is as below

<xsl:template match="/">
    <SalesOrder>
      <xsl:apply-templates select="GenomicOrder/SalesOrder"/>
      <ProductionOrders>
        <xsl:apply-templates select="GenomicOrder/ProductionOrder"/>
      </ProductionOrders>
    </SalesOrder>
  </xsl:template>

SalesOrder.OrderId=1234; SalesOrder.ProductionOrder =null;

My successful production order xslt Transformation is as below

<xsl:template match="/">
        <SalesOrder>
          <ProductionOrders>
            <xsl:apply-templates select="GenomicOrder/ProductionOrder"/>
          </ProductionOrders>
          <xsl:apply-templates select="GenomicOrder/SalesOrder"/>
        </SalesOrder>
</xsl:template>

SalesOrder.OrderId=null; SalesOrder.ProductionOrder.OrderRef = 12345;

is there any changes that i can do to deserialize all the objects in one pass. I have transformations written for both "GenomicOrder/ProductionOrder" and "GenomicOrder/SalesOrder".

I am not sure I understand the problem, assuming you want to wrap all elements following a SalesOrder element you can use an approach like

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

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:template match="GenomicOrder">
    <xsl:copy>
      <xsl:for-each-group select="*" group-starting-with="SalesOrder">
        <SalesOrder>
          <xsl:copy-of select="node(), current-group() except ."/>
        </SalesOrder>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

That XSLT 2.0 stylesheet, when run with Saxon 9.4 on the input

 <GenomicOrder>
  <SalesOrder>
    ....
  </SalesOrder>
  <ProductionOrder>
    ....
  </ProductionOrder>
  <ProductionOrder>
    ....
  </ProductionOrder>
  <ProductionOrder>
    ....
  </ProductionOrder>
</GenomicOrder>

outputs

<GenomicOrder>
   <SalesOrder>
    ....
  <ProductionOrder>
    ....
  </ProductionOrder>
      <ProductionOrder>
    ....
  </ProductionOrder>
      <ProductionOrder>
    ....
  </ProductionOrder>
   </SalesOrder>
</GenomicOrder>

You might need to post more details on your XML input structure if my suggestion does not help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM