Intro to XML and JSON #3: XML Items & Keys
Tags: xml, json, tutorial, beginners
Published: 2019-04-03 11:47:51

---
title: Intro to XML and JSON #3: XML Items & Keys
published: true
tags: xml,json,tutorial,beginners
series: "Intro to XML and JSON"
cover_image: https://katiekodes.com/images/xml-json-intro-header-en.png
canonical_url: https://katiekodes.com/intro-xml-json-3/
---

We’ve seen XML from a “[30,000-foot view](https://dev.to/katiekodes/intro-to-xml-and-json-56co).”  
  
We understand [what kind of data](https://dev.to/katiekodes/intro-to-xml-and-json-2-datas-shape-3iji) XML can help us with.  
  
**Let’s learn how to write XML!**

This gets a little detailed, so I’m breaking it into 3 posts published on the same day to give you a coffee break.

In this first of three posts on XML, we’ll cover three topics:

1. The punctuation you use to indicate an “item”
2. The punctuation you use to “nest” items inside each other
3. The 2 punctuation options XML gives you to add “key-value pairs” to an item

_([Click here](https://dev.to/katiekodes/intro-to-xml-and-json-2-datas-shape-3iji/#items-keys-amp-values) if you need a refresher on what I mean by items, keys, and values.)_

* * *

![](https://katiekodes.com/images/booksmany.jpg)

## Posts In This Series

1. Overview {% link https://dev.to/katiekodes/intro-to-xml-and-json-56co %}
2. Tables vs. Lists _(this post)_ {% link https://dev.to/katiekodes/intro-to-xml-and-json-2-datas-shape-3iji %}
3. XML 1 {% link https://dev.to/katiekodes/intro-to-xml-and-json-3-xml-items-keys-1m7i %}
4. XML 2 {% link https://dev.to/katiekodes/dying-intro-to-xml-and-json-4-xml-values-5bi1 %}
5. XML 3 {% link https://dev.to/katiekodes/intro-to-xml-and-json-5-xml-csv-conversions-45n5 %}
6. JSON {% link https://dev.to/katiekodes/intro-to-xml-and-json-6-json-30h3 %}
7. Recap {% link https://dev.to/katiekodes/intro-to-xml-and-json-7-recap-and-real-world-use-5586 %}

---

![](https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/XML_icon.svg/500px-XML_icon.svg.png)

## Items in XML:  the "Element" / "Tagset"

We talked about data having "items," "keys," & "values" in the last post.

In XML, the "item" is called an "element."

The punctuation that XML uses to define the beginning and end of an "element" is a "tagset."

A "tagset" looks like this:

```xml
<Person></Person>
```

**The format is:**

1. A word is repeated twice.
2. Each occurrence of the word is surrounded by less-than and greater-than signs, forming a "tag."
3. Hence, together, they are called a "tagset."
4. The second "tag" is distinguished from the first by having a forward-slash _("`/`")_ immediately after its less-than sign.
5. The first "tag" is meant to indicate the beginning of the element.
6. The second "tag" is meant to indicate the end of the element.

**Note:**  The fact that the tagset _exists in your text file_ means that it _exists as a conceptual "**item**" in your data_.

### Empty Elements

It doesn't matter whether or not there's anything typed between the tags _(after the first greater-than, before the last less-than)_.

The "element" is still a conceptual item that "exists" in your data, simply because you bothered to create a "tagset" to represent it.

If it doesn't have anything between the tags, you can think of it a little like a row full of nothing but commas in a CSV file.

It's still there!

It's just blank.

In fact,  there's even a fancy shortcut for typing "empty" tagsets.

This _single_ tag is equivalent to a tagset with nothing in the middle like the one above.

Note the **forward-slash before its greater-than sign**:

```xml
<Person/>
```

---

![](https://katiekodes.com/images/nestedratsinbread-wide.jpg)

## Nesting Elements

I compared our "blank" **element** _(or "**item**")_ to an empty CSV file **row**, but it has a pretty big difference from an empty CSV file row:  it has a name!

**Elements having names** is a **key aspect of XML**.

The fact that elements each have a name also enables XML to have _two_ approaches to indicating an element's "keys+values," whereas JSON only has one approach.

That can give XML flexibility and also make it **confusing**.

Worse yet is that people don't always choose between the two approaches for consistent reasons.

1. Sometimes they choose in ways that help them accurately **represent their data**.  We'll talk about that a lot in the text that follows.
2. Other times, it seems like they simply choose "approach #1" because it takes up **vertical** space and avoid "approach #2" because it takes up **horizontal** space when you include line breaks and whitespace in XML for human readability.
  * Humans don't typically like to scroll in both directions when reading large data files. 🤷🏿

[Here's one W3Schools teacher's opinion about best practice](https://www.w3schools.com/xml/xml_dtd_el_vs_attr.asp).

Knowing that everything we're about to learn might be completely ignored by someone else, let's dive in anyway and take a detailed look at both of XML's approaches to defining elements' "keys" and "values."

---

![](https://katiekodes.com/images/numbercircle-01.png)

### "Keys" & their "Values" - Approach 1 ("more tagsets")

The first approach is to nest an element inside an element.

Consequently, the inner element's name isn't just functioning as its name.

By virtue of being nested, the inner element's name is _also_ functioning as a "**key**" indicating some **aspect** of the **outer element**.

Here's an example of "nested" elements in XML:

```xml
<Shirt>
 <Color></Color>
 <Fabric></Fabric>
</Shirt>
```

There are 3 conceptual "items," or "elements," in this data, each of which has a name.

Even though two elements are nested inside the third, **all 3 can stand alone as "elements" in the grammar of XML**.

* **Q:**  Don't believe me?
* **A:**  You can do the same thing with English grammar!  Look:

> You can write an English sentence that has multiple complete sentences inside of it; to write a sentence with multiple complete sentences inside, simply separate the two with semicolons.

The fact that the elements named "color" and "fabric" are nested between the tags of the element named "shirt" means that they are _also_ indicating that this particular shirt has keys named "color" and "fabric" _(the values to both of which are currently blank)_.

---

![](https://katiekodes.com/images/numbercircle-02.png)

### "Keys" & their "Values" - Approach 2 ("attributes")

The second approach is to define a key as an "attribute" of an "element" _("item")_.

* An "attribute" is typed inside the opening tag of a tagset, after the name of the element, separated from it or from other attributes by whitespace.
* An "attribute" consists of a **key** and a **value**, separated by an equals sign (`=`).
  * The **key** goes to the left of the `=` and does not need any quotes around it.
  * The **value** goes to the right of the `=` in single or double quotes.

[Here's some advice about writing XML element attributes from Microsoft](https://msdn.microsoft.com/en-us/library/ms256152(v=vs.110).aspx).

This time using approach #2, let's indicate again that we have a **shirt** with a "**color**" and a "**fabric**," but that the values for "color" & "fabric" are **blank**.

```xml
<Shirt Color="" Fabric=""></Shirt>
```

Or, in shortcut notation, since there's now nothing inside the "Shirt" tagset:

```xml
<Shirt Color="" Fabric=""/>
```

The **main thing to remember** about the second approach is that "color" and "fabric" are **not standalone elements**.

They are "**attributes**" of the element named "Shirt".

![](https://katiekodes.com/images/russiandolls-wide.jpg)

#### "Attributes":  no further nesting allowed

You **can't** put more standalone "elements" between the quotes after the "=" of an "attribute."  You're done.  Only a plain-text value can go there.

You **can't** do this:

```xml
<Shirt Color="" Fabric="<Washable></Washable>"></Shirt>
```

Whereas if you were using approach #1 to nesting, you could do this:

```xml
<Shirt>
 <Color></Color>
 <Fabric>
  <Washable></Washable>
 </Fabric>
</Shirt>
```

![](https://katiekodes.com/images/twinbabies.jpg)

#### "Attributes":  no duplicate keys allowed

You also **can't** give any element more than one "attribute" of the same name.

You **can't** do this:

```xml
<Shirt Color="" Color="" Fabric=""></Shirt>
```

Whereas if you were using approach #1 to nesting, you could do this:

```xml
<Shirt>
 <Color></Color>
 <Color></Color>
 <Fabric></Fabric>
</Shirt>
```

---

![](https://katiekodes.com/images/nightstars-wide.jpg)

## Beware "true emptiness" versus "text with 0 characters"

Note that "color" and "fabric" are truly _**empty**_ in approach #1, but "blank text" _(`""`)_ in approach #2.

If you're using a computer to process an existing XML file, these concepts might be interpreted differently.

One might argue that:

1. there's more of a "nothingness" in the nested-tags example _(it truly doesn't have a color)_, whereas:
2. there's more of a "value without any letters in it"-ness in the attributes example.

If you're processing XML-formatted data with a tool that makes such a distinction, you may have to explicitly instruct your tool to look for _**either**_ "truly blank" _**or**_ "empty text" whenever you, as a business rule, believe they should be treated as equivalent to each other.

---

![](https://katiekodes.com/images/question-confused.jpg)

## Don't mix styles confusingly

A word of warning about mixing the two approaches -- this is _valid_ XML, but hard to make sense of.

```xml
<Shirt Color="" Fabric="">
 <Color></Color>
 <Color></Color>
 <Fabric>
  <Washable></Washable>
 </Fabric>
</Shirt>
```

A human might look at the shirt above and think it has:

1. 3 colors
2. 2 fabrics

However, a computer trying to read the XML would disagree with the human.

So please don't write XML like the example above, because it's confusing.

If you have the misfortune of needing to read XML written in this style by someone else, it's a good idea to get in the habit of reading it the way the computer thinks of it.

In other words, think of the shirt as having:

1. 1 color attribute
2. 1 fabric attribute
3. 2 full-on elements nested within it, each named "color"
4. 1 full-on element nested within it named "fabric"

That way, if you ever need to write or understand code that helps read the XML file, you'll be able to design or follow the code's logic more effectively.

---

![](https://katiekodes.com/images/shoppingbags.jpg)

## Takeaways

Items are defined by giving them names and putting them inside punctuation called "tagsets."

Once you've defined an item, it's known as an "element."

To define key-value pairs for a given "element," XML lets you choose one of two approaches:

 1. Nest an element inside of an element.  The inner element's name serves as a "**key**" for its parent element, and the contents of the inner element serve as the "**value**" for that key.
   * The more "[Russian dolls](https://en.wikipedia.org/wiki/Matryoshka_doll)"-like or "siblings"-like your data looks, the more likely you'll need this approach.
 2. Give the opening tag of an element "attributes."
   * Concise when your data lets you use it, but no "nested nesting" or "duplicate keys" allowed with this approach.

For any given type of key _(such as "color" of a shirt)_, it's best to pick one of the two approaches and stick to it throughout the entire piece of XML you're writing.  That will help avoid confusing people.