AMPscript Looping

This example shows how to loop through xml payloads using AMPscript. We’ll break this process into few different steps.

  1. Review the xml data structured.
  2. Review the data extension.
  3. Writing logic that loads the xml into the email.
  4. Write logic to include safeguards for error handling.
  5. Write logic to loop through xml nodes.
  6. Review the code output.

Reviewing the XML Data Structure

The goal is to write AMPscript logic that will loop through all nodes. This is a screenshot of what the XML payload looks like. You’ll notice that the entire <catalog> contains multiple <book> nodes that we’ll eventually loop through with AMPscript. Additionally, you’ll also notice that for every <book> node it contains data for that specific book’s ID, Author, Title, and Genre. You can download the sample data for this tutorial by clicking here.

<?xml version='1.0' encoding='UTF-8'?>
<catalog>
<book>
<id>001</id>
<author>Liu Cixin</author>
<title>The Three-Body Problem</title>
<genre>Science Fiction</genre>
</book>
<book>
<id>002</id>
<author>Andy Weir</author>
<title>The Martian</title>
<genre>Science Fiction</genre>
</book>
<book>
<id>003</id>
<author>Ernest Cline</author>
<title>Ready Player One</title>
<genre>Science Fiction</genre>
</book>
</catalog>
View this gist on GitHub

Reviewing the Data Extension

The goal is to write AMPscript logic that will load and loop through this XML from within the email. You’ll notice that we have three use cases mocked up below. The 2nd and 3rd use case represent negative test scenarios. This means that our AMPscript safeguards should raise an error whenever there is missing and or incomplete data. You can download the sample data for this tutorial by clicking here.

  1. Subscriber with complete XML data.
  2. Subscriber with no XML data.
  3. Subscriber with incomplete XML data.

Looping through XML with AMPscript

This example shows you how you can loop through XML with AMPscript. In this example you’ll notice that we are doing the following:

  1. Taking the XML data from the [XML] field in the sendable DE and assigning that to a variable called @XML
  2. Write AMPscript logic that uses the BuildRowSetFromXML() function to then build rows based on however many <book> nodes are available.
  3. Write AMPscript logic that sets up safeguards to handle missing XML data.
  4. Write AMPscript logic that sets up safeguards to handle incomplete XML data.
  5. Write AMPscript logic so that the the BuildRowSetFromXML() function and the AMPscript for loop only run if the XML data exists.
<!-- Example Code -->
%%[
/**
* Looping Through XML Payload Data Demo
* This example consumes the XML payload that's stored in the [XML] field.
* This example loops through all <book> nodes and renders book details in the email.
* This example uses RaiseError() when there is no xml payload data to parse.
* This example uses RaiseError() when there are no <book> in the xml payload.
*/
SET @XML = [XML]
IF NOT EMPTY(@XML) THEN
/**
* Looping Through Books
* This block of code examins all <book> nodes from the XML payload.
* This block of code counts the number of <book> nodes from the XML payload.
* This block of code creates a loop that runs for however many <books> are in the payload.
*/
SET @books = BuildRowsetFromXML(@XML,"//catalog/book",1)
SET @book_rows = RowCount(@books)
IF @book_rows > 0 THEN
/**
* Loop Start
* This loop runs for however many books were identified with RowCount()
*/
FOR @i = 1 to @book_rows DO
SET @book = concat("<root>", Field(Row(@books,@i),"Xml"), ",</root>")
/**
* Book Details
* Desc: For each loop iteration identify what the Book ID is.
* Mapping: <catalog><book><id></id></book></catalog>
*/
SET @item_id = BuildRowsetFromXML(@book,"//id",1)
IF RowCount(@item_id) >= 1 THEN
SET @book_id = Field(Row(@item_id,1),"Value")
ELSE
SET @book_id = ""
ENDIF
/**
* Book Details
* Desc: For each loop iteration identify what the book author is.
* Mapping: <catalog><book><author></author></book></catalog>
*/
SET @item_author = BuildRowsetFromXML(@book,"//author",1)
IF RowCount(@item_author) >= 1 THEN
SET @book_author = Field(Row(@item_author,1),"Value")
ELSE
SET @book_author = ""
ENDIF
/**
* Book Details
* Desc: For each loop iteration identify what the book title is.
* Mapping: <catalog><book><title></title></book></catalog>
*/
SET @item_title = BuildRowsetFromXML(@book,"//title",1)
IF RowCount(@item_title) >= 1 THEN
SET @book_title = Field(Row(@item_title,1),"Value")
ELSE
SET @book_title = ""
ENDIF
/**
* Book Details
* Desc: For each loop iteration identify what the book genre is.
* Mapping: <catalog><book><genre></genre></book></catalog>
*/
SET @item_genre = BuildRowsetFromXML(@book,"//genre",1)
IF RowCount(@item_genre) >= 1 THEN
SET @book_genre = Field(Row(@item_genre,1),"Value")
ELSE
SET @book_genre = ""
ENDIF
]%%
<!-- Book Details -->
<p>
Book ID: %%=v(@book_id)=%%<br>
Book Author: %%=v(@book_author)=%%<br>
Book Title: %%=v(@book_title)=%%<br>
Book Genre: %%=v(@book_genre)=%%
</p>
%%[
/* next book */
next @i
ELSE
/**
* Error Handling Safeguard
* Throw a RaiseError() when the xml payload has no book data to show.
* Kill the send for that one subscriber and not the entire job.
*/
RaiseError("The xml payload has no book data.", true)
ENDIF
ELSE
/**
* Error Handling Safeguard
* Throw a RaiseError() if there is no xml data to consume.
* Kill the send for that one subscriber and not the entire job.
*/
RaiseError("There is no xml payload to use.", true)
ENDIF
]%%
<!-- Example Output -->
Book ID: 001
Book Author: Liu Cixin
Book Title: The Three-Body Problem
Book Genre: Science Fiction
Book ID: 002
Book Author: Andy Weir
Book Title: The Martian
Book Genre: Science Fiction
Book ID: 003
Book Author: Ernest Cline
Book Title: Ready Player One
Book Genre: Science Fiction
View this gist on GitHub

Gallery