Migration Center self-serve inbound content pipelines | Transform and Load guide
Inbound content pipelines are a set of capabilities that let you self-configure inbound content feeds from external content sources such as legacy CMS systems or third-party content providers (such as The Associated Press and Getty Images). The new feature set extends Migration Centerβs existing loading capabilities to help you more quickly map external content formats from external sources to Arc XPβs internal format by generating content maps and then using our extended Migration Center APIs to transform and load content at scale.
Whether you are a customer developer, an Arc XP development partner tasked with migrating large volumes of content to Arc XP from a legacy CMS, or a client who needs to create βlive ingestβ pipelines of content from third-party providers, Arc XPβs inbound content pipelines provide a toolkit to help you create those integrations with more speed and reliability than writing your integrations directly to Draft API. Additionally, the toolkit is designed to be completely self-service, meaning you have control over your integration without needing input or assistance from Arc XP development staff.
Prerequisites
- Your organization must be provisioned in Migration Center
- Your organization must be provisioned with ANS Mapper UI
- You should be familiar with the Migration Center API
- You should be familiar with the respective query tooling for source document types based on the data format you are loading.
Overall process
The overall process consists of two key steps. The following sections describe these actions in detail.
- Create an ANS map in Migration Center for converting your source document to ANS
- Use the source ingestion endpoint to import data
Creating an ANS map
To bring external content into Arc XP, you must map that content to Arc XPβs native specification format, or ANS. You can use our content mapping tool in Migration Center to create this content map; however, you must know how to properly format and work with the data. Β
Creating an ANS map in Migration Center
For full documentation on content mappings, see Creating an ANS mapping.
ANS map example
The following example shows a sample Associated Press media story with aggregated content in the source JSON and setting the ANS type to story
.
Multiple source documents for a single output document
When using the ANS mapper and the Migration Center source ingestion API, you use only one source document and one mapping template at a time. This means for scenarios where you have multiple source documents generated by multiple processes that map to a single output document, you must aggregate them together in a single queryable format first before loading when applying your mapping template.
Multiple output documents in a single source document
If you have a single source that can generate multiple output types or related content, then you can upload the source document twice for each mapping template, for example, if you have a source document that generates a story and corresponding images.
It is expected that you make one story map and one image map using the same source document. This means uploading the source document twice at this time for testing in the ANS Mapper tool and for actual transformations in the Migration Center source ingestion API.
Breaking up the source document to only contain what you need for the transformation is optional. All requests to Migration Center have a maximum request size of 6 MB.
View a JSON example of an Associated Press media story with aggregated content
{ "meta": { "products": [ { "id": 30119, "name": "AP Washington State News - No Weather" }, { "id": 30598, "name": "AP National News Report (A Wire)" }, { "id": 30599, "name": "AP Sports News (S Wire only)" }, { "id": 40820, "name": "AP Washington State - Sports only" }, { "id": 41664, "name": "AP Top News" }, { "id": 42435, "name": "AP Top News - Sports - Stories" }, { "id": 100373, "name": "MC Complete - State & National" }, { "id": 100502, "name": "Member Choice Sports Option" }, { "id": 100518, "name": "AP Top News Package" } ], "followed_topics": [] }, "item": { "uri": "https://api.ap.org/media/v2.2/content/9168682d0e18e5fcad1baecee8b69fa3?qt=lPQ8ZbcYV-F&et=5a1aza0c0&in_my_plan=true", "altids": { "itemid": "9168682d0e18e5fcad1baecee8b69fa3", "etag": "9168682d0e18e5fcad1baecee8b69fa3_5a1aza0c0", "friendlykey": "164759759447", "referenceid": "BBO--Home Run Derby" }, "version": 5, "type": "text", "urgency": 4, "profile": "Spot Development", "language": "en", "versioncreated": "2023-07-11T04:24:19Z", "firstcreated": "2023-07-11T01:41:03Z", "editorialrole": "FullStory", "pubstatus": "usable", "ednote": "Eds: UPDATES: with new lead, new photo links, video links. With AP Photos.", "editorialtypes": ["Lead"], "signals": ["newscontent"], "title": "BBO--Home Run Derby", "headline": "Vladimir Guerrero joins Vladimir Sr. as first father-son Home Run Derby winners", "headline_extended": "Torontoβs Vladimir Guerrero Jr, joined Vladimir Sr. to become the first father-son duo to win the All-Star Home Run Derby, beating Tampa Bayβs Randy Arozarena 25-23 in the final round", "slugline": "BC-BBO--Home Run Derby, 5th Ld-Writethru", "description_summary": "Torontoβs Vladimir Guerrero Jr, joined Vladimir Sr. to become the first father-son duo to win the All-Star Home Run Derby, beating Tampa Bayβs Randy Arozarena 25-23 in the final round. Guerrero defeated Julio RodrΓguez 21-20 in the semifinals after the Mariners star hit a record 41 in the first round in front of his hometown fans. Batting against Blue Jays manager John Schneider, Guerrero was the last of the four semifinalists to swing and the first of the finalists, setting a final round record for homers to top Pete Alonsoβs 23 two years ago. Vladimir Sr. won the 2007 derby.", "bylines": [ { "by": "By RONALD BLUM", "title": "AP Baseball Writer" }, { "by": "By Jane Doe", "title": "AP Sports Writer" }, { "by": "By Jack Smith", "title": "AP Writer" } ], "located": "SEATTLE", "datelinelocation": { "city": "Seattle", "countryareacode": "WA", "countryareaname": "Washington", "countrycode": "USA", "countryname": "United States", "geometry_geojson": { "type": "Point", "coordinates": [-122.33207, 47.60621] } }, "copyrightnotice": "Copyright 2023 The Associated Press. All rights reserved. This material may not be published, broadcast, rewritten or redistributed without permission.", "usageterms": [ "This content is intended for editorial use only. For other uses, additional clearances may be required." ], "keywords": ["home run derby julio rodriguez pete alonso"], "provider": "AP", "infosource": [ { "name": "AP", "type": "AP" } ], "person": [ { "scheme": "http://cv.ap.org/id/", "code": "fa25ca7f2ead3d0fb19297f56897868f", "name": "Ken Griffey Jr.", "creator": "Machine", "rels": ["direct"], "types": ["PROFESSIONAL_ATHLETE", "SPORTS_FIGURE", "PERSON"], "teams": [ { "code": "e8404a863bb74fc991749de07a4ff79c", "name": "Seattle Mariners" } ], "relevance": 41 }, { "scheme": "http://cv.ap.org/id/", "code": "17be22774d004ae4944d05ebd79786fc", "name": "Pete Alonso", "creator": "Machine", "rels": ["direct"], "types": ["PROFESSIONAL_ATHLETE", "SPORTS_FIGURE", "PERSON"], "teams": [ { "code": "12c6685b5d2346a28a54d15b0ebaa022", "name": "New York Mets" } ], "relevance": 57 }, { "scheme": "http://cv.ap.org/id/", "code": "a507390657d44611b998f52968488704", "name": "John Schneider", "creator": "Machine", "rels": ["direct"], "types": ["COACH", "SPORTS_FIGURE", "PERSON"], "teams": [ { "code": "07e1ed4bb7584a3d8c3a341f95be8df3", "name": "Toronto Blue Jays" } ], "relevance": 49 }, { "scheme": "http://cv.ap.org/id/", "code": "07e0d9a5f1123913958de551fb66a468", "name": "Vladimir Guerrero", "creator": "Machine", "rels": ["direct"], "types": ["PROFESSIONAL_ATHLETE", "SPORTS_FIGURE", "PERSON"], "teams": [ { "code": "ba83eb1a77a1437bab584ff84ab2d6b3", "name": "Baltimore Orioles" } ], "relevance": 76 }, { "scheme": "http://cv.ap.org/id/", "code": "d9b531d78a3c3d4a8e5f152ccd1bb752", "name": "Vladimir Guerrero Jr.", "creator": "Machine", "rels": ["direct"], "types": ["PROFESSIONAL_ATHLETE", "SPORTS_FIGURE", "PERSON"], "teams": [ { "code": "07e1ed4bb7584a3d8c3a341f95be8df3", "name": "Toronto Blue Jays" } ], "relevance": 43 }, { "scheme": "http://cv.ap.org/id/", "code": "774de8d614d247bfb628d68446710679", "name": "Randy Arozarena", "creator": "Machine", "rels": ["direct"], "types": ["PROFESSIONAL_ATHLETE", "SPORTS_FIGURE", "PERSON"], "teams": [ { "code": "9018285be375430bab2167ae81d4754c", "name": "Tampa Bay Rays" } ], "relevance": 66 } ], "subject": [ { "rels": ["category"], "creator": "Editorial", "code": "s", "name": "s" }, { "rels": ["category"], "creator": "Editorial", "code": "a", "name": "a" }, { "rels": ["category"], "creator": "Editorial", "code": "n", "name": "n" }, { "scheme": "http://cv.ap.org/id/", "code": "20d82ae87e4e100488a0d0913b2d075c", "name": "Baseball", "creator": "Machine", "rels": ["direct"], "relevance": 96 }, { "scheme": "http://cv.ap.org/id/", "code": "94aaa8f88c0c100489d7b9433d2f4c0e", "name": "MLB baseball", "creator": "Machine", "rels": ["direct"], "relevance": 96 }, { "scheme": "http://cv.ap.org/id/", "code": "a4677d70863b4012b846a1b00f5079f5", "name": "U.S. news", "creator": "Editorial", "editorial_subject": "U.S. news", "rels": ["direct"], "relevance": 75 }, { "scheme": "http://cv.ap.org/id/", "code": "f25af2d07e4e100484f5df092526b43e", "name": "General news", "creator": "Editorial", "editorial_subject": "General news", "rels": ["direct"], "relevance": 50 }, { "scheme": "http://cv.ap.org/id/", "code": "54df6c687df7100483dedf092526b43e", "name": "Sports", "creator": "Editorial", "editorial_subject": "Sports", "rels": ["direct"], "relevance": 99 } ], "organisation": [ { "scheme": "http://cv.ap.org/id/", "code": "cb9064a3502342e183423e4bbbd7ded3", "name": "Chicago White Sox", "creator": "Machine", "rels": ["direct"], "relevance": 32 }, { "scheme": "http://cv.ap.org/id/", "code": "07e1ed4bb7584a3d8c3a341f95be8df3", "name": "Toronto Blue Jays", "creator": "Machine", "rels": ["direct"], "relevance": 71 }, { "scheme": "http://cv.ap.org/id/", "code": "a22c87218b6f496ba912505fe4528b68", "name": "Los Angeles Dodgers", "creator": "Machine", "rels": ["direct"], "relevance": 32 }, { "scheme": "http://cv.ap.org/id/", "code": "5cf57e1f36d74864aa45142fd41628d7", "name": "Los Angeles Angels", "creator": "Machine", "rels": ["direct"], "relevance": 32 } ], "audiences": [ { "code": "82c6a4c46fa0446090a7acaf93159e4c", "name": "Print", "type": "AUDPLATFORM" }, { "code": "9add4649b53b4702ba7d9de5d4fa607a", "name": "Online", "type": "AUDPLATFORM" }, { "code": "f43adc08760d10048040e6e7a0f4673e", "name": "National", "type": "AUDSCOPE" }, { "code": "f4ecf9b0760d10048044e6e7a0f4673e", "name": "International", "type": "AUDSCOPE" }, { "code": "f5b16ea8760d10048047e6e7a0f4673e", "name": "State", "type": "AUDSCOPE" }, { "code": "661850e07d5b100481f5c076b8e3055c", "name": "Latin America and Caribbean", "type": "AUDGEOGRAPHY" }, { "code": "08a0a00882c810048942df092526b43e", "name": "Washington", "type": "AUDGEOGRAPHY" }, { "code": "661e48387d5b10048291c076b8e3055c", "name": "United States", "type": "AUDGEOGRAPHY" } ], "associations": { "1": { "uri": "https://api.ap.org/media/v2.2/content/369ad9b07ebc4cd5a38544b7d54d8b89?qt=lPQ8ZbcYV-F&et=0a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "369ad9b07ebc4cd5a38544b7d54d8b89", "etag": "369ad9b07ebc4cd5a38544b7d54d8b89_0a2aza3c0" }, "version": 0, "type": "picture", "headline": "All Star Home Run Derby Baseball" }, "2": { "uri": "https://api.ap.org/media/v2.2/content/98a1a81dedae4db383b036c5a210e4f3?qt=lPQ8ZbcYV-F&et=1a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "98a1a81dedae4db383b036c5a210e4f3", "etag": "98a1a81dedae4db383b036c5a210e4f3_1a2aza3c0" }, "version": 1, "type": "picture", "headline": "Home Run Derby Baseball" }, "3": { "uri": "https://api.ap.org/media/v2.2/content/9b23ec196ad34d389b6e9313ab67b3f4?qt=lPQ8ZbcYV-F&et=0a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "9b23ec196ad34d389b6e9313ab67b3f4", "etag": "9b23ec196ad34d389b6e9313ab67b3f4_0a2aza3c0" }, "version": 0, "type": "picture", "headline": "Run Derby Baseball" }, "4": { "uri": "https://api.ap.org/media/v2.2/content/97845dc1889043e6afa6ad637881a40f?qt=lPQ8ZbcYV-F&et=0a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "97845dc1889043e6afa6ad637881a40f", "etag": "97845dc1889043e6afa6ad637881a40f_0a2aza3c0" }, "version": 0, "type": "picture", "headline": "All Star Home Run Derby Baseball" }, "5": { "uri": "https://api.ap.org/media/v2.2/content/9b3c9505299b40189b6ec2cc16e4696e?qt=lPQ8ZbcYV-F&et=0a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "9b3c9505299b40189b6ec2cc16e4696e", "etag": "9b3c9505299b40189b6ec2cc16e4696e_0a2aza3c0" }, "version": 0, "type": "picture", "headline": "All Star Home Run Derby Baseball" }, "6": { "uri": "https://api.ap.org/media/v2.2/content/2b2b7d82412f4d379de07a135f86efc3?qt=lPQ8ZbcYV-F&et=0a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "2b2b7d82412f4d379de07a135f86efc3", "etag": "2b2b7d82412f4d379de07a135f86efc3_0a2aza3c0" }, "version": 0, "type": "picture", "headline": "All Star Home Run Derby Baseball" }, "7": { "uri": "https://api.ap.org/media/v2.2/content/e66a361abcd74f11821fe40ea69d8d73?qt=lPQ8ZbcYV-F&et=0a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "e66a361abcd74f11821fe40ea69d8d73", "etag": "e66a361abcd74f11821fe40ea69d8d73_0a2aza3c0" }, "version": 0, "type": "picture", "headline": "All Star Home Run Derby Baseball" }, "8": { "uri": "https://api.ap.org/media/v2.2/content/d210cc4c27af44478734dfb6a1a8554f?qt=lPQ8ZbcYV-F&et=0a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "d210cc4c27af44478734dfb6a1a8554f", "etag": "d210cc4c27af44478734dfb6a1a8554f_0a2aza3c0" }, "version": 0, "type": "picture", "headline": "All Star Home Run Derby Baseball" }, "9": { "uri": "https://api.ap.org/media/v2.2/content/7d71233a2ac34db4806ace08e1b1feac?qt=lPQ8ZbcYV-F&et=0a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "7d71233a2ac34db4806ace08e1b1feac", "etag": "7d71233a2ac34db4806ace08e1b1feac_0a2aza3c0" }, "version": 0, "type": "picture", "headline": "All Star Home Run Derby Baseball" }, "10": { "uri": "https://api.ap.org/media/v2.2/content/39f6f12d86724a60bfff13c80d991062?qt=lPQ8ZbcYV-F&et=0a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "39f6f12d86724a60bfff13c80d991062", "etag": "39f6f12d86724a60bfff13c80d991062_0a2aza3c0" }, "version": 0, "type": "picture", "headline": "All Star Home Run Derby Baseball" }, "11": { "uri": "https://api.ap.org/media/v2.2/content/b1d4b5bea6fe41239c4f814d2bf495ff?qt=lPQ8ZbcYV-F&et=0a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "b1d4b5bea6fe41239c4f814d2bf495ff", "etag": "b1d4b5bea6fe41239c4f814d2bf495ff_0a2aza3c0" }, "version": 0, "type": "picture", "headline": "All Star Home Run Derby Baseball" }, "12": { "uri": "https://api.ap.org/media/v2.2/content/d18dad6cd0504efbb217c4b0ce250bb4?qt=lPQ8ZbcYV-F&et=0a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "d18dad6cd0504efbb217c4b0ce250bb4", "etag": "d18dad6cd0504efbb217c4b0ce250bb4_0a2aza3c0" }, "version": 0, "type": "picture", "headline": "All Star Home Run Derby Baseball" }, "13": { "uri": "https://api.ap.org/media/v2.2/content/153d27e6e2a8402eba98d41df7285779?qt=lPQ8ZbcYV-F&et=0a2aza3c0&ai=9168682d0e18e5fcad1baecee8b69fa3&in_my_plan=true", "altids": { "itemid": "153d27e6e2a8402eba98d41df7285779", "etag": "153d27e6e2a8402eba98d41df7285779_0a2aza3c0" }, "version": 0, "type": "picture", "headline": "All Star Home Run Derby Baseball" } }, "renditions": { "nitf": { "title": "NITF Story Download", "rel": "Story", "format": "IIM", "type": "text", "mimetype": "text/xml", "fileextension": "xml", "words": 764, "contentid": "41ead9df1a60bd366f333dfa735fa842", "href": "https://api.ap.org/media/v2.2/content/9168682d0e18e5fcad1baecee8b69fa3.5/download?type=text&format=NITF&rid=41ead9df1a60bd366f333dfa735fa842&cid=0&fid=55ec7f6e6d6b49c78ba673ab475cd88e&trf=a0484&qt=lPQ8ZbcYV-F&dt=-OKsxE1bQD&et=5a1aza0c0", "mediafilterid": "2", "content": "<nitf xmlns=\"http://iptc.org/std/NITF/2006-10-18/\" version=\"-//IPTC//DTD NITF 3.4//EN\" change.date=\"October 18, 2006\" change.time=\"19:30\">\n <head>\n <docdata>\n <doc-id regsrc=\"AP\"/>\n <date.issue norm=\"20230711T042419Z\"/>\n <ed-msg info=\"Eds: UPDATES: with new lead, new photo links, video links. With AP Photos.\"/>\n <doc.copyright holder=\"AP\" year=\"2023\"/>\n <identified-content>\n <classifier type=\"apcategorycode\" value=\"s\"/>\n <classifier type=\"apcategorycode\" value=\"a\"/>\n <classifier type=\"apcategorycode\" value=\"n\"/>\n </identified-content>\n </docdata>\n </head>\n <body>Vladimir Guerrero joins Vladimir Sr. as first father-son Home Run Derby winnersBy RONALD BLUMAP Baseball WriterThe Associated PressSEATTLETorontoβs Vladimir Guerrero Jr, joined Vladimir Sr. to become the first father-son duo to win the All-Star Home Run Derby, beating Tampa Bayβs Randy Arozarena 25-23 in the final round. Guerrero defeated Julio RodrΓguez 21-20 in the semifinals after the Mariners star hit a record 41 in the first round in front of his hometown fans. Batting against Blue Jays manager John Schneider, Guerrero was the last of the four semifinalists to swing and the first of the finalists, setting a final round record for homers to top Pete Alonsoβs 23 two years ago. Vladimir Sr. won the 2007 derby. SEATTLE (AP) β Of course a Junior had to do something special in Seattle. Vladimir Guerrero Jr. won the All-Star Home Run Derby on Monday night, matching Vladimir Sr.'s 2007 title to become the first father-son duo to accomplish the feat. As far as who might win a head-to-head swing-off, well, that depends. βIt's kind of difficult right now,β the Toronto Blue Jays star said with a wide grin, speaking through a translator. βWith the time, with the minutes, I'll win. If it's by outs, he'll win.β In a ballpark made famous by the Mariners' Ken Griffey Jr. a generation earlier, Guerrero beat Tampa Bay's Randy Arozarena 25-23 in the final round. He was 8 when his father won the crown in San Francisco. βI donβt remember much about 2007,\" Vladimir Jr. said. βI guess I was too young.β Guerrero totaled 5 1/2 miles of homers β 29,390 feet to be exact. He defeated Julio RodrΓguez 21-20 in the semifinals after the Mariners star hit a record 41 in the first round in front of his hometown fans. Batting against Blue Jays manager John Schneider, Guerrero was the last semifinalist to swing and the first finalist, setting a final round record for homers to top the mark Pete Alonso set when he beat Guerrero 23-22 in 2019. With Guerrero Jr. catching his breath while watching, Arozarena hit against Tampa Bay field coordinator Tomas Francisco. Arozarena had 21 homers in his initial 2 minutes. He had 23 with 7 seconds left in his automatic 30 seconds of bonus time before lining and popping up on his final four swings. Guerrero had 1 minute of bonus time, earning an additional 30 seconds because he twice reached 440 feet. βObviously, the power that he has was incredible,β Arozarena said through a translator. βFor me, I felt good going into that round. But also he was able to get a minute of bonus time. I only had the 30 seconds of bonus time.β Vladimir Guerrero Sr. won the 2007 derby while with the Los Angeles Angels, beating the Blue Jaysβ Alex Rios 3-2 in the final. Arozarena had the most overall homers over the three rounds, 82 to Guerrero's 72, and the most distance at 33,077 feet. Arozarena overcame Luis Robert of the Chicago White Sox 35-22 in the semifinals. Robert hit the longest drive of the night, a 484-foot shot to left in the second round. That topped the high of 476 feet by Barry Bonds in the 2001 derby in Seattle. Trying to become the youngest Derby winner at age 22, RodrΓguez knocked out Alonso, a two-time champion who hit 21. RodrΓguez beat Corey Seager 32-24 in the first round last year at Dodger Stadium, then knocked out Alonso 31-23 before losing to Juan Soto 19-18 in the final. Arozarena beat Texasβ Adolis GarcΓa 24-17 in the opening pairing before a crowd of 46,952 at T-Mobile Park. GarcΓa is the godfather to Arozarenaβs daughter, and the two jumped into each otherβs arms during warmups. Robert knocked out Baltimoreβs Adley Rutschman 28-27 in the opening round. Rutschman hit 21 left-handed, and the switch hitter then turned around to the right side and hit six more right-handed during a 30-second bonus round. From Portland, Oregon, Rutschman grew up attending Mariners games. Guerrero, back for the first time in four years, defeated the Los Angeles Dodgersβ Mookie Betts 26-11 in the first round. Four years ago at Cleveland, Guerrero hit 29 in the first round and 40 in the second, then lost to Alonso in the final. Alonso was trying for his third title in four years. Griffey Jr. is the only three-time winner, taking the title in 1994, β98 and β99. Guerrero Sr. was a nine-time All-Star but never won a World Series. He was inducted into the Hall of Fame in 2018. Guerrero Jr. is a three-time All-Star and was MVP of the game two years ago in Denver. What's in the future? A World Series ring? Joining dad in the Hall? βIβm a little bit too young to think about that right now,β he said. βWhen I get there, then Iβll think about it, Iβll see if I match my dad or was better than my dad or not.β ___ AP MLB: https://apnews.com/hub/MLB and https://twitter.com/AP_Sports <body.content>\n <block>\n <p>SEATTLE (AP) β Of course a Junior had to do something special in Seattle.</p>\n <p>\n <a href=\"https://www.mlb.com/video/vlad-guerrero-jr-wins-2023-derby?partnerId=web_video-playback-page_video-share\">Vladimir Guerrero Jr.</a> won the All-Star Home Run Derby on Monday night, matching Vladimir Sr.'s 2007 title to become the first father-son duo to accomplish the feat.</p>\n <p>As far as who might win a head-to-head swing-off, well, that depends.</p>\n <p>βIt's kind of difficult right now,β the Toronto Blue Jays star said with a wide grin, speaking through a translator. βWith the time, with the minutes, I'll win. If it's by outs, he'll win.β</p>\n <p>In a ballpark made famous by the Mariners' Ken Griffey Jr. a generation earlier, Guerrero beat <a href=\"https://www.mlb.com/video/arozarena-s-23-homers-in-finals?partnerId=web_video-playback-page_video-share\">Tampa Bay's Randy Arozarena</a> 25-23 in the final round. He was 8 when his father won the crown in San Francisco.</p>\n <p>βI donβt remember much about 2007,\" Vladimir Jr. said. βI guess I was too young.β</p>\n <p>Guerrero totaled 5 1/2 miles of homers β 29,390 feet to be exact. He defeated Julio RodrΓguez 21-20 in the semifinals after the Mariners star hit a record 41 in the first round in front of his hometown fans. </p>\n <p>Batting against Blue Jays manager John Schneider, Guerrero was the last semifinalist to swing and the first finalist, setting a final round record for homers to top the mark Pete Alonso set when he beat Guerrero 23-22 in 2019.</p>\n <p>With Guerrero Jr. catching his breath while watching, Arozarena hit against Tampa Bay field coordinator Tomas Francisco. Arozarena had 21 homers in his initial 2 minutes. <a href=\"https://www.mlb.com/video/arozarena-s-23rd-hr-of-the-finals?partnerId=web_video-playback-page_video-share\">He had 23 with 7 seconds left in his automatic 30 seconds of bonus time before lining and popping up on his final four swings</a>.\n </p>\n <p>Guerrero had 1 minute of bonus time, earning an additional 30 seconds because he twice reached 440 feet.</p>\n <p>βObviously, the power that he has was incredible,β Arozarena said through a translator. βFor me, I felt good going into that round. But also he was able to get a minute of bonus time. I only had the 30 seconds of bonus time.β</p>\n <p>Vladimir Guerrero Sr. won the 2007 derby while with the Los Angeles Angels, beating the Blue Jaysβ Alex Rios 3-2 in the final.</p>\n <p>Arozarena had the most overall homers over the three rounds, 82 to Guerrero's 72, and the most distance at 33,077 feet. Arozarena overcame Luis Robert of the Chicago White Sox 35-22 in the semifinals. Robert hit the longest drive of the night, a 484-foot shot to left in the second round. That topped the high of 476 feet by Barry Bonds in the 2001 derby in Seattle.</p>\n <p>Trying to become the youngest Derby winner at age 22, RodrΓguez knocked out Alonso, a two-time champion who hit 21. RodrΓguez beat Corey Seager 32-24 in the first round last year at Dodger Stadium, then knocked out Alonso 31-23 before losing to Juan Soto 19-18 in the final.</p>\n <p>Arozarena beat Texasβ Adolis GarcΓa 24-17 in the opening pairing before a crowd of 46,952 at T-Mobile Park. GarcΓa is the godfather to Arozarenaβs daughter, and the two jumped into each otherβs arms during warmups.</p>\n <p>\n <a href=\"https://www.mlb.com/video/robert-jr-s-28-round-1-homers?partnerId=web_video-playback-page_video-share\">Robert knocked out Baltimoreβs Adley Rutschman 28-27</a> in the opening round. Rutschman hit 21 left-handed, and <a href=\"https://apnews.com/article/adley-rutschman-home-run-derby-de7290bb10aa7046e3b5928831da83a2\">the switch hitter</a> then <a href=\"https://www.mlb.com/video/adley-rutschman-switches-sides?partnerId=web_video-playback-page_video-share\">turned around to the right side and hit six more right-handed</a> during a 30-second bonus round. From Portland, Oregon, Rutschman grew up attending Mariners games.</p>\n <p>Guerrero, back for the first time in four years, <a href=\"https://www.mlb.com/video/guerrero-jr-s-26-round-1-homers?partnerId=web_video-playback-page_video-share\">defeated the Los Angeles Dodgersβ Mookie Betts 26-11</a> in the first round. Four years ago at Cleveland, <a href=\"https://apnews.com/article/56dbc7f1203b444fb1fb37d3385d84e9\">Guerrero hit 29 in the first round and 40 in the second, then lost to Alonso in the final</a>. \n </p>\n <p>Alonso was trying for his third title in four years. Griffey Jr. is the only three-time winner, taking the title in 1994, β98 and β99.</p>\n <p>Guerrero Sr. was a nine-time All-Star but never won a World Series. He was inducted into the Hall of Fame in 2018.</p>\n <p>Guerrero Jr. is a three-time All-Star and was MVP of the game two years ago in Denver. What's in the future? A World Series ring? Joining dad in the Hall?</p>\n <p>βIβm a little bit too young to think about that right now,β he said. βWhen I get there, then Iβll think about it, Iβll see if I match my dad or was better than my dad or not.β </p>\n <p>___</p>\n <p>AP MLB: <a href=\"https://apnews.com/hub/MLB\">https://apnews.com/hub/MLB</a> and <a href=\"https://twitter.com/AP_Sports\">https://twitter.com/AP_Sports</a>\n </p>\n </block>\n </body.content>\n</body>\n</nitf>" } }, "textformat": "bx", "links": [ { "href": "https://apnews.com/article/home-run-derby-julio-rodriguez-pete-alonso-9168682d0e18e5fcad1baecee8b69fa3", "rel": "canonical" } ] }}
Validating your ANS map
After you create an ANS map in Migration Center, validate the ANS map to confirm it is not generating any errors. See Validating a mapping.
When the ANS is validated, save the map by clicking Save.
View the corresponding mapping template for generating the ANS document
{ "id": "1699672679252", "name": "AP Embedded Story", "documentType": "json", "mappings": [ { "targetPath": "ANS._id", "conditions": [ true, "item.renditions.nitf.contentid != null" ], "actions": [ { "type": "def", "query": "item.renditions.nitf.contentid" }, { "type": "fn", "name": "generateArcHash", "params": [ { "hash": "staging" } ] } ] }, { "targetPath": "ANS.type", "actions": [ { "type": "def", "set": "story" } ] }, { "targetPath": "ANS.version", "actions": [ { "type": "def", "set": "0.10.9" } ] }, { "targetPath": "ANS.canonical_website", "actions": [ { "type": "def", "set": "staging" } ] }, { "targetPath": "ANS.comments", "actions": [ { "type": "def", "set": { "allow_comments": false, "display_comments": false, "moderation_required": false } } ] }, { "targetPath": "ANS.content_restrictions", "actions": [ { "type": "def", "set": { "content_code": "ap_wires_content", "embargo": { "active": true } } } ] }, { "targetPath": "ANS.copyright", "actions": [ { "type": "def", "query": "item.copyrightnotice" } ] }, { "targetPath": "ANS.credits.by", "actions": [ { "type": "def", "query": "item.bylines" }, { "type": "fn", "name": "map", "params": [ { "mappings": [ { "targetPath": "type", "actions": [ { "type": "def", "set": "author" } ] }, { "targetPath": "name", "actions": [ { "type": "def", "query": "by" }, { "type": "fn", "name": "replaceText", "params": [ { "pattern": "By ", "replacement": "" } ] } ] }, { "targetPath": "org", "actions": [ { "type": "def", "query": "title" } ] }, { "targetPath": "affiliation", "actions": [ { "type": "def", "query": "title" } ] } ] } ] } ] }, { "targetPath": "ANS.description.basic", "actions": [ { "type": "def", "query": "item.headline_extended" } ] }, { "targetPath": "ANS.display_date", "actions": [ { "type": "def", "query": "item.versioncreated" }, { "type": "fn", "name": "toDate" } ] }, { "targetPath": "ANS.distributor.mode", "actions": [ { "type": "def", "set": "reference" } ] }, { "targetPath": "ANS.distributor.reference_id", "actions": [ { "type": "def", "set": "4e36c6d6-f9c9-46f3-9b1e-218007f5690d" } ] }, { "targetPath": "ANS.headlines.basic", "actions": [ { "type": "def", "query": "item.headline" } ] }, { "targetPath": "ANS.language", "actions": [ { "type": "def", "query": "item.language" } ] }, { "targetPath": "ANS.location", "actions": [ { "type": "def", "query": "item.located" } ] }, { "targetPath": "ANS.planning.budget_line", "actions": [ { "type": "def", "query": "item.slugline" } ] }, { "targetPath": "ANS.planning.internal_note", "actions": [ { "type": "def", "query": "item.ednote" } ] }, { "targetPath": "ANS.planning.scheduling.planned_publish_date", "actions": [ { "type": "def", "query": "item.versioncreated" }, { "type": "fn", "name": "toDate" } ] }, { "targetPath": "ANS.planning.scheduling.will_have_image", "actions": [ { "type": "def", "set": true } ] }, { "targetPath": "ANS.slug", "actions": [ { "type": "def", "query": "item.slugline" } ] }, { "targetPath": "ANS.source.source_id", "actions": [ { "type": "def", "query": "item.altids.itemid" } ] }, { "targetPath": "ANS.source.system", "actions": [ { "type": "def", "set": "ArcXP Exchange" } ] }, { "targetPath": "ANS.status", "actions": [ { "type": "def", "query": "item.pubstatus" } ] }, { "targetPath": "ANS.subheadlines.basic", "actions": [ { "type": "def", "query": "item.headline_extended" } ] }, { "targetPath": "ANS.subtype", "actions": [ { "type": "def", "set": "ap-wires-story" } ] }, { "targetPath": "ANS.syndication", "actions": [ { "type": "def", "set": { "external_distribution": false, "search": false } } ] }, { "targetPath": "ANS.tracking", "actions": [ { "type": "def", "set": { "noindex_nofollow": false } } ] }, { "targetPath": "ANS.workflow", "actions": [ { "type": "def", "set": { "status_code": 1, "note": "Associated Press wires content" } } ] }, { "targetPath": "ANS.additional_properties.originalUrl", "actions": [ { "type": "def", "query": "item.links[0].href" } ] }, { "targetPath": "ANS.additional_properties.sourceRevision", "actions": [ { "type": "def", "query": "item.altids.etag" } ] }, { "targetPath": "ANS.content_elements", "actions": [ { "type": "def", "query": "item.renditions.nitf.content" }, { "type": "fn", "name": "search", "params": [ { "search": "/*[name() = 'nitf']/*[name() = 'body']/*[name() = 'body.content']/child::node()", "type": "xml" } ] }, { "type": "fn", "name": "nitfToANS" } ] }, { "targetPath": "ANS.promo_items.basic", "actions": [ { "type": "def", "query": "item.associations" }, { "type": "fn", "name": "objectValues" }, { "type": "fn", "name": "first" }, { "type": "fn", "name": "map", "params": [ { "mappings": [ { "targetPath": "type", "actions": [ { "type": "def", "set": "reference" } ] }, { "targetPath": "referent.type", "actions": [ { "type": "def", "set": "image" } ] }, { "targetPath": "referent.id", "actions": [ { "type": "def", "query": "altids.itemid" }, { "type": "fn", "name": "generateArcHash", "params": [ { "hash": "staging" } ] } ] } ] } ] } ] }, { "targetPath": "ANS.related_content.basic", "actions": [ { "type": "def", "query": "item.associations" }, { "type": "fn", "name": "objectValues" }, { "type": "fn", "name": "map", "params": [ { "mappings": [ { "targetPath": "type", "actions": [ { "type": "def", "set": "reference" } ] }, { "targetPath": "referent.type", "actions": [ { "type": "def", "set": "image" } ] }, { "targetPath": "referent.id", "actions": [ { "type": "def", "query": "altids.itemid" }, { "type": "fn", "name": "generateArcHash", "params": [ { "hash": "staging" } ] } ] } ] } ] } ] }, { "targetPath": "circulations", "actions": [ { "type": "def", "set": [ { "document_id": null, "website_id": "staging", "website_sections": [ { "type": "reference", "referent": { "type": "section", "website": "staging", "id": "/dogs" } } ], "website_primary_section": { "type": "reference", "referent": { "type": "section", "website": "staging", "id": "/dogs" } } } ] }, { "type": "fn", "name": "map", "params": [ { "mappings": [ { "targetPath": "website_id", "actions": [ { "type": "def", "query": "website_id" } ] }, { "targetPath": "website_sections", "actions": [ { "type": "def", "query": "website_sections" } ] }, { "targetPath": "website_primary_section", "actions": [ { "type": "def", "query": "website_primary_section" } ] }, { "targetPath": "document_id", "actions": [ { "type": "def", "query": "item.renditions.nitf.contentid" }, { "type": "fn", "name": "generateArcHash", "params": [ { "hash": "staging" } ] } ] } ] } ] } ] } ]}
Your generated ANS should translate to the following:
View generated ANS based on the previous source and mapping template
{ "ANS": { "_id": "3VRQ4G6HNVKRRCPJ2ATWP3IJIU", "type": "story", "version": "0.10.9", "canonical_website": "staging", "comments": { "allow_comments": false, "display_comments": false, "moderation_required": false }, "content_restrictions": { "content_code": "ap_wires_content", "embargo": { "active": true } }, "copyright": "Copyright 2023 The Associated Press. All rights reserved. This material may not be published, broadcast, rewritten or redistributed without permission.", "credits": { "by": [ { "type": "author", "name": "RONALD BLUM", "org": "AP Baseball Writer", "affiliation": "AP Baseball Writer" }, { "type": "author", "name": "Jane Doe", "org": "AP Sports Writer", "affiliation": "AP Sports Writer" }, { "type": "author", "name": "Jack Smith", "org": "AP Writer", "affiliation": "AP Writer" } ] }, "description": { "basic": "Torontoβs Vladimir Guerrero Jr, joined Vladimir Sr. to become the first father-son duo to win the All-Star Home Run Derby, beating Tampa Bayβs Randy Arozarena 25-23 in the final round" }, "display_date": "2023-07-11T04:24:19.000Z", "distributor": { "mode": "reference", "reference_id": "4e36c6d6-f9c9-46f3-9b1e-218007f5690d" }, "headlines": { "basic": "Vladimir Guerrero joins Vladimir Sr. as first father-son Home Run Derby winners" }, "language": "en", "location": "SEATTLE", "planning": { "budget_line": "BC-BBO--Home Run Derby, 5th Ld-Writethru", "internal_note": "Eds: UPDATES: with new lead, new photo links, video links. With AP Photos.", "scheduling": { "planned_publish_date": "2023-07-11T04:24:19.000Z", "will_have_image": true } }, "slug": "BC-BBO--Home Run Derby, 5th Ld-Writethru", "source": { "source_id": "9168682d0e18e5fcad1baecee8b69fa3", "system": "ArcXP Exchange" }, "status": "usable", "subheadlines": { "basic": "Torontoβs Vladimir Guerrero Jr, joined Vladimir Sr. to become the first father-son duo to win the All-Star Home Run Derby, beating Tampa Bayβs Randy Arozarena 25-23 in the final round" }, "subtype": "ap-wires-story", "syndication": { "external_distribution": false, "search": false }, "tracking": { "noindex_nofollow": false }, "workflow": { "status_code": 1, "note": "Associated Press wires content" }, "additional_properties": { "originalUrl": "https://apnews.com/article/home-run-derby-julio-rodriguez-pete-alonso-9168682d0e18e5fcad1baecee8b69fa3", "sourceRevision": "9168682d0e18e5fcad1baecee8b69fa3_5a1aza0c0" }, "content_elements": [ { "type": "text", "content": "SEATTLE (AP) β Of course a Junior had to do something special in Seattle.", "additional_properties": {} }, { "type": "text", "content": "\n <a href=\"https://www.mlb.com/video/vlad-guerrero-jr-wins-2023-derby?partnerId=web_video-playback-page_video-share\">Vladimir Guerrero Jr.</a> won the All-Star Home Run Derby on Monday night, matching Vladimir Sr.'s 2007 title to become the first father-son duo to accomplish the feat.", "additional_properties": {} }, { "type": "text", "content": "As far as who might win a head-to-head swing-off, well, that depends.", "additional_properties": {} }, { "type": "text", "content": "βIt's kind of difficult right now,β the Toronto Blue Jays star said with a wide grin, speaking through a translator. βWith the time, with the minutes, I'll win. If it's by outs, he'll win.β", "additional_properties": {} }, { "type": "text", "content": "In a ballpark made famous by the Mariners' Ken Griffey Jr. a generation earlier, Guerrero beat <a href=\"https://www.mlb.com/video/arozarena-s-23-homers-in-finals?partnerId=web_video-playback-page_video-share\">Tampa Bay's Randy Arozarena</a> 25-23 in the final round. He was 8 when his father won the crown in San Francisco.", "additional_properties": {} }, { "type": "text", "content": "βI dont remember much about 2007,\" Vladimir Jr. said. βI guess I was too young.β", "additional_properties": {} }, { "type": "text", "content": "Guerrero totaled 5 1/2 miles of homers β 29,390 feet to be exact. He defeated Julio RodrΓguez 21-20 in the semifinals after the Mariners star hit a record 41 in the first round in front of his hometown fans. ", "additional_properties": {} }, { "type": "text", "content": "Batting against Blue Jays manager John Schneider, Guerrero was the last semifinalist to swing and the first finalist, setting a final round record for homers to top the mark Pete Alonso set when he beat Guerrero 23-22 in 2019.", "additional_properties": {} }, { "type": "text", "content": "With Guerrero Jr. catching his breath while watching, Arozarena hit against Tampa Bay field coordinator Tomas Francisco. Arozarena had 21 homers in his initial 2 minutes. <a href=\"https://www.mlb.com/video/arozarena-s-23rd-hr-of-the-finals?partnerId=web_video-playback-page_video-share\">He had 23 with 7 seconds left in his automatic 30 seconds of bonus time before lining and popping up on his final four swings</a>.\n ", "additional_properties": {} }, { "type": "text", "content": "Guerrero had 1 minute of bonus time, earning an additional 30 seconds because he twice reached 440 feet.", "additional_properties": {} }, { "type": "text", "content": "βObviously, the power that he has was incredible,β Arozarena said through a translator. βFor me, I felt good going into that round. But also he was able to get a minute of bonus time. I only had the 30 seconds of bonus time.β", "additional_properties": {} }, { "type": "text", "content": "Vladimir Guerrero Sr. won the 2007 derby while with the Los Angeles Angels, beating the Blue Jaysβ Alex Rios 3-2 in the final.", "additional_properties": {} }, { "type": "text", "content": "Arozarena had the most overall homers over the three rounds, 82 to Guerrero's 72, and the most distance at 33,077 feet. Arozarena overcame Luis Robert of the Chicago White Sox 35-22 in the semifinals. Robert hit the longest drive of the night, a 484-foot shot to left in the second round. That topped the high of 476 feet by Barry Bonds in the 2001 derby in Seattle.", "additional_properties": {} }, { "type": "text", "content": "Trying to become the youngest Derby winner at age 22, RodrΓguez knocked out Alonso, a two-time champion who hit 21. RodrΓguez beat Corey Seager 32-24 in the first round last year at Dodger Stadium, then knocked out Alonso 31-23 before losing to Juan Soto 19-18 in the final.", "additional_properties": {} }, { "type": "text", "content": "Arozarena beat Texasβ Adolis GarcΓa 24-17 in the opening pairing before a crowd of 46,952 at T-Mobile Park. GarcΓa is the godfather to Arozarenaβs daughter, and the two jumped into each otherβs arms during warmups.", "additional_properties": {} }, { "type": "text", "content": "\n <a href=\"https://www.mlb.com/video/robert-jr-s-28-round-1-homers?partnerId=web_video-playback-page_video-share\">Robert knocked out Baltimoreβs Adley Rutschman 28-27</a> in the opening round. Rutschman hit 21 left-handed, and <a href=\"https://apnews.com/article/adley-rutschman-home-run-derby-de7290bb10aa7046e3b5928831da83a2\">the switch hitter</a> then <a href=\"https://www.mlb.com/video/adley-rutschman-switches-sides?partnerId=web_video-playback-page_video-share\">turned around to the right side and hit six more right-handed</a> during a 30-second bonus round. From Portland, Oregon, Rutschman grew up attending Mariners games.", "additional_properties": {} }, { "type": "text", "content": "Guerrero, back for the first time in four years, <a href=\"https://www.mlb.com/video/guerrero-jr-s-26-round-1-homers?partnerId=web_video-playback-page_video-share\">defeated the Los Angeles Dodgersβ Mookie Betts 26-11</a> in the first round. Four years ago at Cleveland, <a href=\"https://apnews.com/article/56dbc7f1203b444fb1fb37d3385d84e9\">Guerrero hit 29 in the first round and 40 in the second, then lost to Alonso in the final</a>. \n ", "additional_properties": {} }, { "type": "text", "content": "Alonso was trying for his third title in four years. Griffey Jr. is the only three-time winner, taking the title in 1994, β98 and β99.", "additional_properties": {} }, { "type": "text", "content": "Guerrero Sr. was a nine-time All-Star but never won a World Series. He was inducted into the Hall of Fame in 2018.", "additional_properties": {} }, { "type": "text", "content": "Guerrero Jr. is a three-time All-Star and was MVP of the game two years ago in Denver. What's in the future? A World Series ring? Joining dad in the Hall?", "additional_properties": {} }, { "type": "text", "content": "βIβm a little bit too young to think about that right now,β he said. βWhen I get there, then Iβll think about it, Iβll see if I match my dad or was better than my dad or not.β ", "additional_properties": {} }, { "type": "text", "content": "___", "additional_properties": {} }, { "type": "text", "content": "AP MLB: <a href=\"https://apnews.com/hub/MLB\">https://apnews.com/hub/MLB</a> and <a href=\"https://twitter.com/AP_Sports\">https://twitter.com/AP_Sports</a>\n ", "additional_properties": {} } ], "promo_items": { "basic": { "type": "reference", "referent": { "type": "image", "id": "K2AI7KSAVBPJXK5DZUXTRIFKYY" } } }, "related_content": { "basic": [ { "type": "reference", "referent": { "type": "image", "id": "K2AI7KSAVBPJXK5DZUXTRIFKYY" } }, { "type": "reference", "referent": { "type": "image", "id": "AJCFESCHKZIWLLALRCI34VG7JM" } }, { "type": "reference", "referent": { "type": "image", "id": "BCGNB6DKJZMTPDYTLZSUHPWYA4" } }, { "type": "reference", "referent": { "type": "image", "id": "T5NVSWBBNZOSRANFHY6PX63C74" } }, { "type": "reference", "referent": { "type": "image", "id": "TVNWJUMPHZPAJOBRVCVPIUMDOQ" } }, { "type": "reference", "referent": { "type": "image", "id": "ZKBNWYCVEFLJFEKDVRCVZKFSGU" } }, { "type": "reference", "referent": { "type": "image", "id": "J7GK3FW4QVLERNGKS6X6KADIPY" } }, { "type": "reference", "referent": { "type": "image", "id": "LY2U7HZJGVLKLDU5LZFULLHHUE" } }, { "type": "reference", "referent": { "type": "image", "id": "XJH2KUEIKNK6DGFTKKPYU2H7XU" } }, { "type": "reference", "referent": { "type": "image", "id": "F5TA4KOG6ZOMJKPRVNROQ5LNZQ" } }, { "type": "reference", "referent": { "type": "image", "id": "OJGOKI7M2NMYRL3SQJGH3UHDYI" } }, { "type": "reference", "referent": { "type": "image", "id": "GHDUL5LENZMXTJPLMWU7YBJNIM" } }, { "type": "reference", "referent": { "type": "image", "id": "CUABFXTXWRMLZPW4OKBOAPYJKU" } } ] } }, "circulations": [ { "website_id": "staging", "website_sections": [ { "type": "reference", "referent": { "type": "section", "website": "staging", "id": "/dogs" } } ], "website_primary_section": { "type": "reference", "referent": { "type": "section", "website": "staging", "id": "/dogs" } }, "document_id": "3VRQ4G6HNVKRRCPJ2ATWP3IJIU" } ]}
Retrieving the mapID
After testing and verifying that your map transforms as expected, you must retrieve the mapID
. You use the mapID
when when applying the mapping to source data to create ANS.
You can retrieve the mapID
in one of two ways: from the ANS map or from the application URL.
- ANS map - the
mapID
is available in your ANS map, as show in the following example.
- application URL - when you have your ANS map open, the URL displays the
mapid
.
Use the source ingestion endpoint to load source documents
After you create your ANS map, you can call the POST /migrations/v3/content/source
endpoint in the Migration Center API to load a document.
To transform your source content, you must pass the sourceContent
along with the sourceAdditionalProperties
in the body of the request, the result of this action is as follows:
- Migration Center saves your source information and submits it for transformation.Β
- After your source information is transformed, Migration Center saves the output for reference when using the details endpoint. Your map must generate an output that matches Migration Centerβs [Post] ANS ingestion endpoint to avoid a transform failure. See API documentation for endpoint
/migrations/v3/content/ans
. - After your information is saved, itβs forwarded through Migration Centerβs loading system into Arc XP.
- When itβs loaded, you have valid ANS in the Arc XP application for the generated ANS type.
Example of source additional properties:
{ "sourceContent": <AP Media Source Content>, "sourceAdditionalProperties": { "transform": { "mapId": "${Your Map ID}" } }}
After you submit the source document, you can track status with the migration/v3/report/detail
endpoint to verify that you successfully submitted.
When you submit content, your content cycles through the following status: Pending, Queued, Processing, [ANS-specific type statuses]. The process may move quickly, so you might not see all statuses. To see the latest status, refresh the API call.
Creating mapping templates
The mapping templates purpose is to allow a user to locate/query fields in a given source document and assign them to their respective location in Arcβs ANS schema as output.
- When making mapping templates you define a
targetPath
that defines where a query will assign values.Β - Then, you define what your initial value is. This can be either a static value or a query that reads the source document via the
def
action.- Any JSON value is valid for assigning to a
targetPath
.
- Any JSON value is valid for assigning to a
- Then, optionally, if want to manipulate your value or coerce it into a specific format or value, you can specify actions or functions (
fn
) by using an action configuration.Β- Actions are performed 1 at a time and in the order specified in the JSON array.
Below is the documentation about transformation actions that are available when utilizing the mapping schema to transform content.
Mapping Schema
The mapping schema uses a configurable format that can process either JSON (via JMESPath) or XML (via XPath) documents for specifying actions to apply to your target mappings and generate a transformed output.
type MappingTemplate = { documentType: string; // source document type: "json" | "xml" environment?: { xml: { namespaces: { [k: string]: string; }; }; }; mappings: [ // Mapping[] { targetPath: string; // ANS.type strict?: boolean; // default false conditions?: (string | boolean)[]; actions: [ // Action[] { type: "def"; set: "story"; }, { type: "fn"; name: "toUpperCase"; }, ]; }, ];};
// result => // { ANS: { type: 'STORY' } }
Properties of a mapping
targetPath
Β -> The path you want to create in the target ANS output JSON.actions
Β -> The list of actions you want to run to modify or create a value at theΒ targetPath.conditions
Β -> static boolean values or string queries to run to decide whether to map a value.strict
Β -> Primarily for debugging, but useful to force errors on mapping. Errors by default will be silent and will result in undefined mappings.
As you work through mappings, you will see that a mapping is likely needed for each property of a JSON or XML document to map that field to the target JSON document.
Action types
Definition actions
Definitions are simply actions that define the key path and value on top of target output with a static valueΒ set
Β or based on aΒ query
. So, setting the valueΒ 2
Β onΒ "targetPath": "id"
Β creates an objectΒ { "id": 2 }
.
type DefineAction = { type: "def"; set?: string; query?: string | { value: string; type: "json" | "xml" };};
Function actions
type FunctionAction = { type: "fn"; name: string; params: [];};
When applying functions to targets, be aware that you are operating on an underlying value that was previously generated. This means that when reading the documentation, wherever it saysΒ targetΒ it is referring to the underlying target implicitly, not something that must be passed in.
TheΒ paramsΒ are only required when a function calls out that there are parameters to pass in.
As a general note, your parameter mappings must be in an array format, unless otherwise specified by the action definition.
For functions that operate on scalar values, the respective function will call out that it operates on a single scalar value or a list of scalar values. This is a feature provided to avoid situations where you would need to use theΒ mapΒ function to iterate over the scope of a single item.
Supported functions
Arrays
- concat
- filter
- first
- flat
- join
- map
- objectValues
- removeDuplicates
- slice
- sort
- splice
- split
- wrapWithArray
Booleans
- toBoolean
- toBooleanStrict
Date
- nowDate
- toDate
Objects
- wrapWithObject
Strings
- generateArcHash
- htmlDecode
- htmlToANS
- interpolate
- nitfToANS
- replaceText
- search
- selectText
- slugify
- toCapitalize
- toJSON
- toLowerCase
- toString
- toTitleCase
- toUpperCase
- trim
concat(target, params) β {Array.<any>}
A fn
that takes two or more arrays and joins them into a single array.
Parameters:
Name | Type | Description |
---|---|---|
target | Array.<any> | An array to concat your values to. Values are always applied to the end of the array. |
params | object | @see properties |
Properties:
Name | Type | Description |
---|---|---|
values | Array.<any> | params.values: The array to add to the target array. |
Returns:
Type: Array.<any>
filter(target, params) β {Array.<T>}
A fn
that runs the filter query on the target array.
Parameters:
Name | Type | Description |
---|---|---|
target | Array.<T> | An array to apply the filter function to. If the target is not an array, it will be put into an array with target as the sole item. |
params | object | @see properties |
Properties:
Name | Type | Attributes | Description |
---|---|---|---|
query | string | object | The JMESPath or XPath query. If the query is a string, that is the query value, and the query type is based on the document type. Provide a query object to set a query type. |
value | string | The JMESPath or XPath query. | |
type | SupportedFileTypes | <optional> | The query type aka the query engine to use. By default, the query type is based on the document type. However, if you know the target being acted on is of a different type, set this param. For example, if the source document type is XML but the target is a list of non-XML-element strings, then you must set query.type to βJSONβ and query.value to a JMESPath query. |
Returns:
Type: Array.<T>
Examples
// Source document is JSON in which item.images is a list of objects.// Mappings:{ "targetPath": "ANS.media.images", "actions": [ { "type": "def", "query": "item.images" }, { "type": "fn", "name": "filter", "params": [ { "query": "[?by!='John Smith']" } ] } ]}// The first action returns a list of item.images objects that gets passed into the filter fn as// its target. The filter fn returns a list of only the objects whose "by" field is not equal to// "Jonh Smith".
// Source document is XML in which /item/media nodes have a title child node.// Mappings:{ "targetPath": "ANS.media.images", "actions":[ { "type": "def", "query": "/item/media/title/text()" }, { "type": "fn", "name": "filter", "params": [ { "query": { "value": "[?starts_with(@, 'tower') == `false`]", "type": "json" } } ] } ]}// The first action returns a list of text from title nodes ["bridge Y", "tower X", "bridge XYZ"].// This isn't a list of XML nodes but is a JSON array of scalar values, and so we need to specify a// params query object to tell filter to use the "json" query engine. The result of filter is the// list: ["bridge Y", "bridge XYZ"].
// Note that this example is to show what a query object looks like; more likely you would have// queries that return a list of XML nodes instead so that subsequent queries can stay as XPath.// E.g. instead of "/item/media/title/text()", do "/item/media/title" and then the filter query// will be an XPath query.
first(target) β {T}
Extracts only the first item in an array
Parameters:
Name | Type | Description |
---|---|---|
target | T |
Returns:
Type: T
flat(target) β {Array.<any>}
A fn
that takes array sub-elements in a target array and spreads them into the parent array.
Parameters:
Name | Type | Description |
---|---|---|
target | Array.<any> | An array to apply the flat function to. |
Returns:
Type: Array.<any>
generateArcHash(target, params) β {string}
Modifies a target value by turning it into a string and encoding it into an arcId. Values used for your hash key are recommended to be unique for groups of documents.
Parameters:
Name | Type | Description |
---|---|---|
target | any | Β |
params | object | @see properties |
Properties:
Name | Type | Attributes | Description |
---|---|---|---|
hash | string | <optional> | A constant value to use for as your hash key. Is required if hashQuery is not provided. |
hashQuery | string | <optional> | A query string used to locate a hash key. It is required if the hash is not provided. |
Returns:
Type: string
htmlDecode(target) β {string}
Modifies a target string value by decoding named or character references such as: foo © bar ≠ baz &x1D306; qux -> foo B) bar b baz p qux
Parameters:
Name | Type | Description |
---|---|---|
target | string |
Returns:
Type: string
htmlToANS(target) β {Record.<string, unknown>}
Modifies a target string by converting HTML to ANS.
Parameters:
Name | Type | Description |
---|---|---|
target | any |
Returns:
Type: Record.<string, unknown>
interpolate(target, params) β {string}
Modifies a target string value by interpolating by searching for ${?}
and replacing them with queries
Parameters:
Name | Type | Description |
---|---|---|
target | string | Β |
params | Array | @see properties |
Properties:
Name | Type | Description |
---|---|---|
query | string | The query to use to locate values to apply to your target string. |
target | βsource' | 'destβ Note: When set to source, it will apply your queries to your source document. When set to dest it will apply your queries to your target document. |
Returns:
Type: string
join(target, params) β {string}
A fn
to join 2 or more strings together
Parameters:
Name | Type | Description |
---|---|---|
target | Array.<string> | |
params | object | see properties |
Properties:
Name | Type | Description |
---|---|---|
joiner | string | params.joiner: A string to join 2 or more values together |
Returns:
Type: string
map(target, params:) β {T}
Allows iteration over item(s) to execute item-scoped actions. Can be applied to an object or array of objects.
Parameters:
Name | Type | Description |
---|---|---|
target | object | Array.<object> |
params: | MapTemplate | parameters needed to execute |
Returns:
Type: T
nitfToANS(target) β {Record.string, unknown>}
Modifies a target nitf string it into ANS
Parameters:
Name | Type | Description |
---|---|---|
target | any |
Returns:
Type: Record.<string, unknown>
nowDate() β {string}
Returns the current date in UTC ISO String format.
Returns:
Type: string
objectValues(target) β {Array.<T>}
Extracts only the values from a JSON object
Parameters:
Name | Type | Description |
---|---|---|
target | object |
Returns:
Type: Array.<T>
removeDuplicates(target) β {Array.<T>}
Removes duplicate values from scalar arrays.
Parameters:
Name | Type | Description |
---|---|---|
target | Array.<T> |
Returns:
Type: Array.<T>
replaceText(target, params) β {string|Array.<string>}
Modifies a target value by searching the pattern in a string and replacing matches. fn
can be applied to a string or string array.
Parameters:
Name | Type | Description |
---|---|---|
target | string | Array.<string> |
params | object | @see properties |
Properties:
Name | Type | Attributes | Description |
---|---|---|---|
pattern | string | A search pattern used to locate strings to replace | |
flags | string | <optional> | Regular expression flags to apply to your target |
replacement | string | A string value for replacing pattern matches. |
Returns:
Type: string
|Array.<string>
search(target, param) β {string}
A fn
to allow for searching JSON/XML values against targets.
Parameters:
Name | Type | Description |
---|---|---|
target | any | |
param | object |
Properties:
Name | Type | Attributes | Description |
---|---|---|---|
search | string | A query to search the document. | |
defaultValue | string | <optional> | When a query returns a null response the defaultValue will be used |
type | βjson' | 'xmlβ | The type of the target value to search against |
Returns:
Type: string
selectText(target, params) β {string|Array.<string>}
Modifies a target value by getting a substring from text using regex . fn
can be applied to a string or string array. It will return an array if it applies to an array and a string if it applies to a string.
Parameters:
Name | Type | Description |
---|---|---|
target | string | Array.<string> |
params | object | @see properties |
Properties:
Name | Type | Description |
---|---|---|
pattern | string | A regex used to find strings to get |
Returns:
Type: string
|Array.<string>
slice(target, params) β {Array.<any>}
A fn
that removes items at the start to the end index and applies to the target output.
Parameters:
Name | Type | Description |
---|---|---|
target | Array.<any> | An array to apply the splice function to |
params | object | @see properties |
Properties:
Name | Type | Attributes | Description |
---|---|---|---|
start | number | Β | params.start: The position to start from. Starts at 0. |
end | number | <optional> | params.end: The position of the array to end at. |
Returns:
Type: Array.<any>
slugify(target, params) β {string|Array.}
Modifies a target string by turning the string into a slug format. fn
can be applied to strings or an array of strings.
Parameters:
Name | Type | Description |
---|---|---|
target | string | Array.<string> |
params | object | @see properties |
Properties:
Name | Type | Attributes | Description |
---|---|---|---|
useDefaultCharacters | number | <optional> | params.useDefaultCharacters: When set to true, it will apply the following characters: β*β, β+β, β~β, β.β, β(β, β)β, βββ, βββ, β!β, β:β, β@β |
characters | number | <optional> | params.characters: Any additional characters that need to be converted to β-β |
Returns:
- returns a slugged string delimited with β-β
Type: string
|Array.<string>
sort(target) β {Array.<string>|Array.<number>}
Sorts arrays with scalar values by their natural order
Parameters:
Name | Type | Description |
---|---|---|
target | Array.<string> | Array.<number> |
Returns:
Type: Array.<string>
|Array.<number>
splice(target, params) β {Array.<any>}
A fn
that will take an array and remove elements from the target array. May be configured to return the deleted items and apply them to the target output.
Parameters:
Name | Type | Description |
---|---|---|
target | string | An array to apply the splice function to |
params | object | @see properties |
Properties:
Name | Type | Attributes | Description |
---|---|---|---|
start | number | params.start: The position to start from. Starts at 0. | |
deleteCount | number | <optional> | params.deleteCount: The max number of items to delete. |
items | Array. | <optional> | params.items: The items to add to the array after removals. |
returnDeletedItems | Array. | <optional> | params.returnDeletedItems: When set to false it returns the original target after modification. If true returns the deleted items from the array. |
Returns:
Type: Array.<any>
split(target, params) β {Array.<string>}
A fn
to split a string into an array
Parameters:
Name | Type | Description |
---|---|---|
target | string | A string to apply the split function to |
params | object | @see properties |
Properties:
Name | Type | Attributes | Description |
---|---|---|---|
separator | string | params.separator: A string delimiter to split on | |
limit | number | <optional> | params.limit: The max number of delimiters to split on. |
Returns:
Type: Array.<string>
toBoolean(target) β {boolean}
Converts a value to a truthy/falsey value. Can be applied to a single value or an array of values.
Parameters:
Name | Type | Description |
---|---|---|
target | any | Array.<any> A value to convert to a boolean. |
Returns:
Type: boolean
toBooleanStrict(target) β {boolean|Array.<boolean>}
Converts a value strictly to a boolean value, such as: 'true' 'True' / 'False' 'false' -> true / false
. Can be applied to a single value or an array of values.
Parameters:
Name | Type | Description |
---|---|---|
target | any | Array.<any> A value to convert to a boolean. |
Returns:
Type: boolean
|Array.<boolean>
toCapitalize(target) β {string|Array.<string>}
Modifies a target string to capitalize a string. fn
can be applied to strings or an array of strings.
Parameters:
Name | Type | Description |
---|---|---|
target | string | Array.<string> |
Returns:
Type: string
|Array.<string>
toDate(target) β {string}
Converts a value to an UTC ISO String date. Can be applied to a single value or an array of values.
Parameters:
Name | Type | Description |
---|---|---|
target | any | Array.<any> A value to convert to a boolean |
Returns:
Type: string
toJSON(target) β {string}
Modifies a target JS object by converting it into a JSON string.
Parameters:
Name | Type | Description |
---|---|---|
target | any |
Returns:
Type: string
toLowerCase(target) β {string|Array.<string>}
Modifies a target string to a lowercase string. fn
can be applied to strings or an array of strings.
Parameters:
Name | Type | Description |
---|---|---|
target | string | Array.<string> |
Returns:
Type: string
|Array.<string>
toString(target, params) β {string|Array.<string>}
Modifies a target array by turning each element into a string. fn
can be applied to strings or an array of strings.
Parameters:
Name | Type | Description |
---|---|---|
target | any | Array.<string> |
params | object | @see properties |
Returns:
Type: string
|Array.<string>
toTitleCase(target) β {string|Array.<string>}
Modifies a target string to use title casing. fn
can be applied to strings or an array of strings.
Parameters:
Name | Type | Description |
---|---|---|
target | string / Array.<string> | A string array to apply to join value to |
Returns:
Type: string
|Array.<string>
toUpperCase(target) β {string|Array.<string>}
Modifies a target string to an uppercased string. fn
can be applied to strings or an array of strings.
Parameters:
Name | Type | Description |
---|---|---|
target | string / Array.<string> |
Returns:
Type: string
|Array.<string>
trim(target) β {string|Array.<string>}
Modifies a target string by removing spaces on outer bounds of a character area. fn
can be applied to strings or an array of strings.
Parameters:
Name | Type | Description |
---|---|---|
target | string / Array.<string> |
Returns:
Type: string
|Array.<string>
wrapWithArray(target) β {Array.<unknown>}
Wraps a target value inside an Array
Parameters:
Name | Type | Description |
---|---|---|
target | any | A value to wrap inside of an array |
Returns:
Type: Array.<unknown>
wrapWithObject(target) β {object}
Wraps a target value inside an object and the provided key.
Parameters:
Name | Type | Description |
---|---|---|
target | any | A value to wrap inside of an object |
Returns:
Type: object
Mapping Usage
header
The header fields define general information about the map.
{ "id": "1234567890", "name": "Test map", "documentType": "json", "description": "Converts RSS document fragments (captured from an RSS document) into ANS",}
id
- This is an auto-generated ID of the map to reference.name
- Defines the name of the map.documentType
- Defines what type of source document is being used.xml
- for XML source documents. For XML source documents, mapping uses XPath syntax to query source documents. You can find out more about XPath syntax here.json
- for JSON source documents. For JSON source documents, mapping uses JMESPath syntax to query source documents. You can find out more about JMESPath syntax here.
description
- Add a helpful note about what this map is designed to convert.
mappings
The mappings array defines how to build a specific target JSON result.
Each object in the mappings array should:
- The root object must be of type object and must have
targetPath
andactions
properties. targetPath
must be astring
.actions
must be anarray
of objects, each with specific properties:type
must be astring
and can only be either'def'
or'fn'
.- When type is set to def action object can have the following properties:
set
which set static value to target path and can be of typenumber
,integer
,string
,boolean
,array
, orobject
.query
which queries source document (XPath for XML and JMESPath for JSON) and must be astring
containing the query which will use the query engine matching the source document type, or anobject
to use a different query engine. For example, if the source document is XML but you want to query against JSON, then specifyquery: { value: 'a JMESPath query'; type: 'json' }
.
- When type is set to
fn
action object can have the following properties:name
must be a stringparams
must be anarray
with items that can be of typenumber
,integer
,string
,boolean
,array
, orobject
.
- When type is set to def action object can have the following properties:
{ "targetPath": "subheadlines", "actions": [ { "type": "def", "query": "title" } ]}
Will produce in the target JSON
{ "subheadlines": "whatever result comes from querying title of source doc"}
{ "targetPath": "ANS.created_date", "actions": [ { "type": "def", "query": "created" }, { "type": "fn", "name": "toDate" } ]}
Will produce in the target JSON
{ "ANS" : { "created_date": "converts created date from source doc for i.e. 2024-02-06T15:40:00.000Z" }}
static value
The simplest type of mapping is to create a field using a static value like:
"mappings": [ { "targetPath": "type", "actions": [ { "type": "def", "set": "story" } ] }]
This will generate the JSON target
{ "type": "story" }
query source value
The most common use case for a map is to import data from a source document to a new target document.
All examples on this page will use this as the source XML document fragment:
<item> <title>Todays weather forecast </title> <pubDate>22 Oct 2022 13:05:22 GMT </pubDate></item>
Since the source is XML documentType
will be set as xml
.
Letβs add a second object to the mappings array to map the <title>
tag in the source to headlines.basic
in the JSON target. To get the contents of the <title>
tag inside the <item>
tag we use slashes to join the tags in the order we want to search for them, like /item/title
, and append the command text()
to tell it we just want the contents of the tag. XPath always returns values as an array, even from the text function, so the string
function wraps this to define we only want the inner string value.
"mappings": [ { "targetPath": "type", "actions": [ { "type": "def", "set": "story" } ] }, { "targetPath": "headlines.basic", "actions": [ { "type": "def", "query": "string(/item/title/text())" } ] }]
This will generate the following JSON target document:
{ "type": "story", "headlines": { "basic": "Todays weather forecast " }}
Modifying values with function
A common need is to make formatting changes to a source
before it is added to a target. For instance, maybe you want to make the text uppercase. This functionality is provided by defining a function array in any mappings object. There are many out of the box functions
available to use with no code needed in the map.
Letβs add a functions
array to our example mappings object. To remove leading and trailing spaces from the title in our source example we use trim
. To then also make it a Title Case, we use toTitleCase
. These are simple processors that do not need any arguments to do their job, and so all that is needed is to list their names as strings in the order we wish them to be applied, and they will manipulate the value assigned to the targetPath
. So:
{ "targetPath": "type", "actions": [ { "type": "def", "set": "story" } ] }, { "targetPath": "headlines.basic", "actions": [ { "type": "def", "query": "string(/item/title/text())" }, { "type": "fn", "name": "trim" }, { "type": "fn", "name": "toTitleCase" } ] }
Will generate the following JSON target:
{ "type": "story", "headlines": { "basic": "Todays Weather Forecast" }}
conditional value
Sometimes one or more true/false conditions might be needed to determine if a targetPath
should be added to the target document. For this purpose, a conditions
array can be added. If our example XML might sometimes have a <slug>
tag nested in <items>
we could just map it like this:
mappings: [ ... { "targetPath": "slug", "actions": [ { "type": "def", "query": "string(/item/slug/text())" } ] }]
If there is a <slug>
tag inside <item>
then the slug field value will be added as string to the target path slug. But if there isnβt a slug field, nothing will happen. The map engine will not add an empty field, so you donβt need to add conditions on every mappings object.
In the example below when there is no slug tag in the source XML, the output from the first mappings object will be nothing. The second mappings object will evaluate the condition as true, and so it will use the title tagβs content and modify it with the slugify processor to produce the value of slug in the target.
mappings: [ ... { "targetPath": "slug", "conditions": [ true, "string(/item/slug/text()) != null" ], "actions": [ { "type": "def", "query": "string(/item/slug/text())" }, { "type": "fn", "name": "slugify", "params": [ { "useDefaultCharacters": true } ] } ] }]
Generating the following in JSON target document:
{ "slug": "todays-weather-forcast"}