Conversion
CSV to Google Shopping XML
Google Merchant Center reads product data as delimited text or as RSS 2.0 / Atom XML with g: attributes. The mapping below turns a plain product CSV into either. The sample XML is downloadable; the CSV it came from is shown beside it. Most stores find they never needed the XML step: a CSV with Google's column names on a fetchable URL is a valid data source.
We connect your store, build the feed and keep it in sync. Updated 2026-10-27.
At a glance
- Google's XML format is RSS 2.0 with xmlns:g="http://base.google.com/ns/1.0"; every product is an <item> and every attribute is a g:-prefixed element, or it is ignored.
- Google's file formats page lists tab-delimited text (.txt, .tsv) and XML (RSS 2.0 or Atom 1.0), up to 4 GB, optionally gzipped; a delimited text file with Google's column names is the simplest valid feed.
- The conversion is really a renaming plus five fixes: id, price with currency, availability words, plain-text description and absolute URLs.
- Textfinity reads any CSV by URL, maps it to Google's column names and publishes the feed Merchant Center fetches; its output is CSV or TSV, never XML, so if you need XML specifically, use the sample structure here.
CSV columns to Google Shopping XML elements
Each CSV header becomes one g: element inside an <item>. The names on the right are Google's and must be spelled exactly; the names on the left are what a typical store export calls them. The third column is the fix that usually has to happen during the conversion.
| Typical CSV column | Google element | Fix during conversion |
|---|---|---|
| sku | <g:id> | Unique per row, max 50 chars; never reuse an id across variants |
| name | <g:title> | Max 150 chars; combine brand, name, color, size |
| description (HTML) | <g:description> | Strip tags; max 5,000 chars; XML needs & and < escaped or a CDATA block |
| url | <g:link> | Absolute, starts with http or https |
| image | <g:image_link> | Absolute URL to the file, not a page |
| stock (number) | <g:availability> | in_stock, out_of_stock, preorder or backorder |
| price (number) | <g:price> | Number, space, ISO currency: 15.00 USD |
| sale_price (number) | <g:sale_price> | Same format; omit the element when empty |
| brand | <g:brand> | Max 70 chars; required for most new products |
| ean / upc | <g:gtin> | Digits only; omit when unknown |
| condition | <g:condition> | new, used or refurbished (lowercase) |
| category | <g:google_product_category> | Google taxonomy path or numeric id |
| parent_sku | <g:item_group_id> | Shared by all variants of one product |
Element names, limits and the RSS 2.0 structure from Google's product data specification and RSS 2.0 data source help, checked 2026-10-27. Empty attributes should be omitted, not sent blank.
products.csv (the source, before conversion)
sku,name,description,url,image,stock,price,brand,condition,parent_sku
TEE-ORG-NAVY-M,Organic Tee,"<p>Mid-weight organic cotton tee.</p>",/products/organic-tee,/img/tee-navy.jpg,14,29,Northway,New,TEE-ORG
MUG-STONE-BLUE,Stoneware Mug,"<p>Hand-thrown stoneware mug.<br>Dishwasher safe.</p>",/products/stoneware-mug-blue,/img/mug-blue.jpg,0,24,Hearth,New,What the Google Shopping XML looks like
The file is an RSS 2.0 document with the Google namespace declared on the root. The channel needs a title, link and description, and each item carries the g: elements. Attributes without the g: prefix are ignored during processing, which is the single most common reason a hand-built XML feed imports zero products.
feed.xml (one item)
<?xml version="1.0"?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<title>Example store</title>
<link>https://store.example</link>
<description>Product feed</description>
<item>
<g:id>MUG-STONE-BLUE</g:id>
<g:title>Hearth Stoneware Mug, Blue, 350 ml</g:title>
<g:description>Hand-thrown stoneware mug. Dishwasher safe.</g:description>
<g:link>https://store.example/products/stoneware-mug-blue</g:link>
<g:image_link>https://cdn.example/mug-blue.jpg</g:image_link>
<g:availability>in_stock</g:availability>
<g:price>24.00 USD</g:price>
<g:brand>Hearth</g:brand>
<g:condition>new</g:condition>
</item>
</channel>
</rss>The shortcut: you probably do not need XML
Merchant Center fetches product files on a schedule once the URL is added as a product source in its data sources settings; the URL must point at the file and can be up to 4 GB. Google's formats page lists tab-delimited text and XML by extension, and a text file whose header row uses Google's attribute names is processed the same way as the XML above; in practice Merchant Center also fetches comma-delimited CSV, which is what Textfinity's feeds are in production. XML earns its place when a downstream system demands RSS, when descriptions carry characters that break delimited files, or when a partner's importer only reads XML.
That is how Textfinity approaches the conversion: it reads the CSV by URL, we map each column to Google's attribute name with a rename or a rule, and it publishes the result on a stable URL as CSV (or TSV), rebuilt on your shop's schedule. We register that URL with you in Merchant Center as a scheduled fetch. Textfinity never writes XML: if a destination specifically needs an RSS file, the sample download above has the structure to script against, and a short script with a real XML library can write it from Textfinity's CSV.
Five fixes a CSV needs before it is Google Shopping format
- Price: 24 becomes 24.00 USD. In Textfinity we set price with add suffix " USD", after a replace from regexp to normalize decimals first if the source uses commas.
- Availability: 0 / 12 / true become out_of_stock / in_stock. We map availability with the advanced expression if [stock] equals "0" then "out_of_stock" else "in_stock".
- Description: HTML becomes text. We map description with remove from regexp <[^>]+>. In XML, remaining & and < must be escaped.
- Links and images: relative paths become absolute. We map link with add prefix https://store.example/.
- Identifiers: an empty gtin stays empty, a parent SKU becomes item_group_id. We map gtin as a rename and item_group_id as a rename from parent_sku.
Examples
Worked examples, by situation
The same product in the source CSV and in Google Shopping XML, for three kinds of store. The XML shows where each value lands; the Textfinity rules we set up in each example produce the same values as columns of a CSV feed, because Textfinity does not write XML.
A variant row becomes an item with a group id
Before
parent_sku,sku,name,color,size,price,stock TEE-ORG,TEE-ORG-NAVY-M,Organic Tee,Navy,M,29,14
After
<item> <g:id>TEE-ORG-NAVY-M</g:id> <g:item_group_id>TEE-ORG</g:item_group_id> <g:title>Organic Cotton Tee, Navy, M</g:title> <g:color>Navy</g:color> <g:size>M</g:size> <g:price>29.00 USD</g:price> <g:availability>in_stock</g:availability> </item>
How we set it up
We map title as a combine of name, color and size with ", ", item_group_id as a rename from parent_sku, price with add suffix " USD" and availability with an advanced rule on stock. The Google Shopping template supplies the attribute names.
HTML description to plain text
Before
sku,name,description,price MUG-STONE-BLUE,Stoneware Mug,"<p>Hand-thrown <b>stoneware</b> mug.<br>Dishwasher safe.</p>",24
After
<g:id>MUG-STONE-BLUE</g:id> <g:description>Hand-thrown stoneware mug. Dishwasher safe.</g:description> <g:price>24.00 USD</g:price>
How we set it up
We map description with replace from regexp (<[^>]+>|\s)+ to a single space: one rule strips the tags and collapses the gaps, and Textfinity trims the space left at either end of every mapped value. Free listings use the same attributes, so the same feed serves both.
European price format to Google format
Before
art_nr;bezeichnung;preis;lager 88-1201;USB-C Hub 7-in-1;49,90;3
After
<g:id>88-1201</g:id> <g:title>USB-C Hub 7-in-1</g:title> <g:price>49.90 EUR</g:price> <g:availability>in_stock</g:availability>
How we set it up
Textfinity detects the semicolon delimiter on import. We map price with replace from regexp ^(\d+),(\d{2})$ to \1.\2 EUR (one rule fixes the decimal and adds the currency) and availability with the advanced expression if [lager] equals "0" then "out_of_stock" else "in_stock". Column names stay German in the source and become Google's in the feed.
Copy this plan
Plan: from a product CSV to a Merchant Center data source
No converter to install; the file stays where it is and Textfinity reads it by URL. You host the file; we set up the rest.
01
Put the CSV on a URL
A file on your server (HTTPS or SFTP), a cloud bucket link, or a Google Sheet. Textfinity re-reads it on every sync, so a file that your platform regenerates on cron keeps the feed current.
What we set up: We add your CSV URL or Google Sheet as the source in Textfinity.02
Check the profile
The feed hygiene profile shows completeness per column, over-length titles, mixed languages and malformed URLs. Fix what you can at the source; the rest is a rule.
03
Start from the Google Shopping template
Google's attribute names are pre-filled; map each one from your columns using the table above.
What we set up: We start the feed from Textfinity's Google Shopping template.04
Apply the five fixes
Currency suffix, availability expression, HTML removal, absolute URLs, group ids.
What we set up: We set price with add suffix, availability with an advanced expression, description with remove from regexp, link with add prefix and item_group_id as a rename.05
Filter rows Google should not get
Rows with an empty image, price zero or a test SKU.
What we set up: We add filter rules: image is not blank, price is more than 0, sku does not start with TEST.06
Register the feed in Merchant Center
Add the feed URL as a product source in Merchant Center's data sources and set a daily fetch. That form is in Google's interface.
What we set up: We register the URL with you: you give us access to Merchant Center, or we walk you through it.
Customization tips
Make it yours
Escape or CDATA if you hand-build XML
Ampersands in titles ("Black & Decker") break XML unless written as & or wrapped in CDATA. Delimited text has the opposite problem: commas and quotes inside descriptions need quoting. A feed tool handles both; a script needs a real CSV and XML library, not string concatenation.
Omit empty elements instead of sending blanks
Google asks that attributes with no value be removed. In Textfinity, the leave empty transform omits the value; do not add a static "" or "N/A" to satisfy a column.
Keep the source column names, rename in the feed
Changing headers in the source file breaks whoever else reads it. Mapping handles the rename, and the product explorer shows the mapped value per product so you can verify without opening the file.
One feed per currency
A CSV with a price_usd and a price_eur column becomes two feeds with two add suffix rules and two Merchant Center targets; mixing currencies in one file is a disapproval.
Downloads
Take the files
FAQ
Questions about csv to google shopping xml
Does Google Merchant Center require XML?
No. Google's file formats page lists tab-delimited text (.txt, .tsv) and XML (RSS 2.0 or Atom 1.0) by extension, up to 4 GB and optionally compressed. A delimited text file with Google's attribute names in the header is a valid product data source; Merchant Center also fetches Textfinity's comma-delimited CSV in production. XML is one option, not the requirement.
What is the Google Shopping XML format exactly?
An RSS 2.0 document with xmlns:g="http://base.google.com/ns/1.0" on the root, a channel with title, link and description, and one item per product whose attributes are g:-prefixed elements such as g:id, g:title, g:price and g:availability. Elements without the g: prefix are ignored.
Can Textfinity convert my CSV to Google Shopping XML?
Textfinity converts a CSV to the Google Shopping format and publishes it as a CSV or TSV file on a URL that Merchant Center fetches on a schedule. It does not write XML. If a system of yours requires RSS XML specifically, use the sample file on this page as the structure and generate it from the feed with a script.
How do I convert a product feed to Google Shopping format?
Put the CSV on a URL or in a Google Sheet, start from the Google Shopping attribute names, apply the five fixes above and point Merchant Center at the feed URL. A script can do it once; feed software keeps it current. With Textfinity we set up the mapping for you and the software rebuilds the feed on schedule.
Set up for you
Have us turn your CSV into a Google Shopping feed.
Send us the file URL. We map the thirteen columns above in Textfinity, apply the five fixes and register the feed with you in Merchant Center. No converter to install.
Tell us your store and channels. We reply within 24 hours.