XSLT String Wrap:How do I wrap words in a String a

2019-03-03 23:20发布

问题:

We want to write XSLT transformation for given XML. We are trying to text wrap for comment element at newline character on pressing of ENTER KEY. In that, <Comment> elements Splits across 6 different line items after applying XSLT Transformation.

Note: Here "\n" is the linefeed character. It means end the present line and go to a new line.

We tried following :

Pattern observed in it:
<StockCode> element is blank for all having comment substring at each line items. while StockCode element is having value for all those <comment> element is blank
<OrderDetail> is repeating node here.

Input XML :

<?xml version="1.0" encoding="WINDOWS-1252"?>

-<SalesOrders xsd:noNamespaceSchemaLocation="SORTOIDOC.XSD" xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance">

-<Orders>

-<OrderHeader>

<Customer>000016</Customer>
<OrderDate>2016-04-19</OrderDate>
<SalesForceOrderNumber>ORD-411324</SalesForceOrderNumber>
</OrderHeader>
-<OrderDetails>
-<StockLine>
<StockCode>ABB-CDE-FGH-01</StockCode>
<OrderDescription>EDIORDER-SAVE COMMENTS C3 Generic LOC 0833 Expected arrival 01/07/2016  OTYPE NE TRKPC 01 GM/00007643020008361321</OrderDescription>
</comment>
<OrderLineID>OR-1561179</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>

-<OrderDetails> ---------------------
-<StockLine>
<StockCode>Nil</StockCode>
</Comment>
<OrderLineID>OR-1561180</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>
-<OrderDetails>
-<StockLine>
<StockCode>Nil</StockCode>
</Comment>
<OrderLineID>OR-1561181</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>
-<OrderDetails>
-<StockLine>
<StockCode>Nil</StockCode>
</Comment>
<OrderLineID>OR-1561182</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>
-<OrderDetails>
-<StockLine>
<StockCode>Nil</StockCode>
</Comment>
<OrderLineID>OR-1561183</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>
-<OrderDetails>
-<StockLine>
<StockCode>Nil</StockCode>
</Comment>
<OrderLineID>OR-1561184</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders

Expected XML After XSLT transformation:

<?xml version="1.0" encoding="WINDOWS-1252"?>

-<SalesOrders xsd:noNamespaceSchemaLocation="SORTOIDOC.XSD" xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance">

-<Orders>

-<OrderHeader>

<Customer>000016</Customer>
<OrderDate>2016-04-19</OrderDate>
<SalesForceOrderNumber>ORD-411324</SalesForceOrderNumber>
</OrderHeader>
-<OrderDetails>
-<StockLine>
<StockCode>ABB-CDE-FGH-01</StockCode>
<Comment>Nil</Comment>
<OrderLineID>OR-1561179</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>

-<OrderDetails> ---------------------
-<StockLine>
<StockCode>Nil</StockCode>
<Comment>EDIORDER-SAVE COMMENTS</Comment>
<OrderLineID>OR-1561180</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>
-<OrderDetails>
-<StockLine>
<StockCode>Nil</StockCode>
<Comment>C3 Generic</Comment>
<OrderLineID>OR-1561181</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>
-<OrderDetails>
-<StockLine>
<StockCode>Nil</StockCode>
<Comment>LOC 0833</Comment>
<OrderLineID>OR-1561182</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>
-<OrderDetails>
-<StockLine>
<StockCode>Nil</StockCode>
<Comment>OTYPE NE</Comment>
<OrderLineID>OR-1561183</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders>
-<OrderDetails>
-<StockLine>
<StockCode>Nil</StockCode>
<Comment>TRKPC 01 GM/00007643020008361321</Comment>
<OrderLineID>OR-1561184</OrderLineID>
</StockLine>
</OrderDetails>
</Orders>
</SalesOrders

The above code splits into 6 diffrent line items(that is for each OrderLineID) In that,we are trying to Achieve Substring on comment field.

How to Write XSLT transformation file for Comment Substring at new line character?

Thanks in Advance !

回答1:

To minimize the problem to the main question here, consider the following stylesheet:

XSLT 2.0

<xsl:stylesheet version="2.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="*"/>

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

<xsl:template match="OrderDetails">
    <xsl:copy>
        <xsl:variable name="stockcode" select="StockLine/StockCode" />
        <xsl:for-each select="tokenize(StockLine/Comment, '\\n')">
            <StockLine>
                <xsl:copy-of select="$stockcode"/>
                <Comment>
                    <xsl:value-of select="normalize-space(.)"/>
                </Comment>
                <OrderLineID>???</OrderLineID>
            </StockLine>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Applied to the following input:

XML

<SalesOrders xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORTOIDOC.XSD">
  <Orders>
    <OrderHeader>
      <Customer>000016</Customer>
      <OrderDate>2016-04-19</OrderDate>
      <SalesForceOrderNumber>ORD-411324</SalesForceOrderNumber>
    </OrderHeader>
    <OrderDetails>
      <StockLine>
        <StockCode>NIL</StockCode>
        <Comment>EDIORDER-SAVE COMMENTS\n C3 Generic\n LOC 0833\n Expected arrival 01/07/2016\n  OTYPE NE\n TRKPC 01 GM/00007643020008361321</Comment>
      </StockLine>
    </OrderDetails>
  </Orders>
</SalesOrders>

the result will be:

<?xml version="1.0" encoding="UTF-8"?>
<SalesOrders xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance"
             xsd:noNamespaceSchemaLocation="SORTOIDOC.XSD">
   <Orders>
      <OrderHeader>
         <Customer>000016</Customer>
         <OrderDate>2016-04-19</OrderDate>
         <SalesForceOrderNumber>ORD-411324</SalesForceOrderNumber>
      </OrderHeader>
      <OrderDetails>
         <StockLine>
            <StockCode>NIL</StockCode>
            <Comment>EDIORDER-SAVE COMMENTS</Comment>
            <OrderLineID>???</OrderLineID>
         </StockLine>
         <StockLine>
            <StockCode>NIL</StockCode>
            <Comment>C3 Generic</Comment>
            <OrderLineID>???</OrderLineID>
         </StockLine>
         <StockLine>
            <StockCode>NIL</StockCode>
            <Comment>LOC 0833</Comment>
            <OrderLineID>???</OrderLineID>
         </StockLine>
         <StockLine>
            <StockCode>NIL</StockCode>
            <Comment>Expected arrival 01/07/2016</Comment>
            <OrderLineID>???</OrderLineID>
         </StockLine>
         <StockLine>
            <StockCode>NIL</StockCode>
            <Comment>OTYPE NE</Comment>
            <OrderLineID>???</OrderLineID>
         </StockLine>
         <StockLine>
            <StockCode>NIL</StockCode>
            <Comment>TRKPC 01 GM/00007643020008361321</Comment>
            <OrderLineID>???</OrderLineID>
         </StockLine>
      </OrderDetails>
   </Orders>
</SalesOrders>

I have no idea where the contents of OrderLineID are supposed to come from.


Important:

If the input Comment contains actual linefeed characters - IOW, if your actual input is:

XML

<SalesOrders xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORTOIDOC.XSD">
  <Orders>
    <OrderHeader>
      <Customer>000016</Customer>
      <OrderDate>2016-04-19</OrderDate>
      <SalesForceOrderNumber>ORD-411324</SalesForceOrderNumber>
    </OrderHeader>
    <OrderDetails>
      <StockLine>
        <StockCode>NIL</StockCode>
        <Comment>EDIORDER-SAVE COMMENTS
C3 Generic
LOC 0833
Expected arrival 01/07/2016
 OTYPE NE
TRKPC 01 GM/00007643020008361321</Comment>
      </StockLine>
    </OrderDetails>
  </Orders>
</SalesOrders>

then use:

<xsl:for-each select="tokenize(StockLine/Comment, '\n')">

Added:

Given the following input:

XML

<SalesOrders xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORTOIDOC.XSD">
  <Orders>
    <OrderHeader>
      <Customer>000016</Customer>
      <OrderDate>2016-04-19</OrderDate>
      <SalesForceOrderNumber>ORD-411324</SalesForceOrderNumber>
    </OrderHeader>
    <OrderDetails>
      <StockLine>
        <StockCode>ABB-CDE-FGH-01</StockCode>
        <OrderDescription>EDIORDER-SAVE COMMENTS
C3 Generic
LOC 0833
Expected arrival 01/07/2016
 OTYPE NE
TRKPC 01 GM/00007643020008361321</OrderDescription>
        <OrderLineID>OR-1561179</OrderLineID>
      </StockLine>
      <StockLine>
        <StockCode>Nil</StockCode>
        <OrderLineID>OR-1561180</OrderLineID>
      </StockLine>
      <StockLine>
        <StockCode>Nil</StockCode>
        <OrderLineID>OR-1561181</OrderLineID>
      </StockLine>
      <StockLine>
        <StockCode>Nil</StockCode>
        <OrderLineID>OR-1561182</OrderLineID>
      </StockLine>
      <StockLine>
        <StockCode>Nil</StockCode>
        <OrderLineID>OR-1561183</OrderLineID>
      </StockLine>
      <StockLine>
        <StockCode>Nil</StockCode>
        <OrderLineID>OR-1561184</OrderLineID>
      </StockLine>
    </OrderDetails>
  </Orders>
</SalesOrders>

the following stylesheet:

XSLT 2.0

<xsl:stylesheet version="2.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="*"/>

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

<xsl:template match="StockLine">
    <xsl:variable name="i" select="position()" />
    <xsl:copy>
        <xsl:copy-of select="StockCode"/>
        <Comment>
            <xsl:value-of select="normalize-space(tokenize(../StockLine[1]/OrderDescription, '\n')[$i])"/>
        </Comment>
        <xsl:copy-of select="OrderLineID"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

will return:

Result

<?xml version="1.0" encoding="UTF-8"?>
<SalesOrders xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance"
             xsd:noNamespaceSchemaLocation="SORTOIDOC.XSD">
   <Orders>
      <OrderHeader>
         <Customer>000016</Customer>
         <OrderDate>2016-04-19</OrderDate>
         <SalesForceOrderNumber>ORD-411324</SalesForceOrderNumber>
      </OrderHeader>
      <OrderDetails>
         <StockLine>
            <StockCode>ABB-CDE-FGH-01</StockCode>
            <Comment>EDIORDER-SAVE COMMENTS</Comment>
            <OrderLineID>OR-1561179</OrderLineID>
         </StockLine>
         <StockLine>
            <StockCode>Nil</StockCode>
            <Comment>C3 Generic</Comment>
            <OrderLineID>OR-1561180</OrderLineID>
         </StockLine>
         <StockLine>
            <StockCode>Nil</StockCode>
            <Comment>LOC 0833</Comment>
            <OrderLineID>OR-1561181</OrderLineID>
         </StockLine>
         <StockLine>
            <StockCode>Nil</StockCode>
            <Comment>Expected arrival 01/07/2016</Comment>
            <OrderLineID>OR-1561182</OrderLineID>
         </StockLine>
         <StockLine>
            <StockCode>Nil</StockCode>
            <Comment>OTYPE NE</Comment>
            <OrderLineID>OR-1561183</OrderLineID>
         </StockLine>
         <StockLine>
            <StockCode>Nil</StockCode>
            <Comment>TRKPC 01 GM/00007643020008361321</Comment>
            <OrderLineID>OR-1561184</OrderLineID>
         </StockLine>
      </OrderDetails>
   </Orders>
</SalesOrders>