Статьи

Подходы к XML — Часть 1 — XML ​​не является строкой …

XML существует уже давно: по памяти я бы предположил, что ему сейчас 12-14 лет; это зрелый продукт, с вычислительной точки зрения, с длинной историей. Итак, есть что-нибудь новое, что я мог бы добавить к этой теме? То, как вы подходите к XML, действительно зависит от вас и вашей ситуации, с акцентом на ситуацию . С одной стороны, вы можете участвовать в уютном «внутреннем» проекте, где одна внутренняя система должна общаться с другой. С другой стороны, вы находитесь в ситуации, когда вам передают XML-схему, которая однажды будет включать в себя диалог между вашей системой и какой-либо другой системой в далекой стране, написанный другим набором разработчиков.

Как обычно, чтобы продемонстрировать различные подходы к XML, я собираюсь взять полностью надуманный и возмутительный сценарий, и в этом сценарии вы работаете в Pete’s Perfect Pizza 1 , который является небольшим магазином на главной улице, но У Пита большие идеи, и первое, что он хочет сделать, — это автоматически отправлять заказы со стойки регистрации на кухню, и он просит вас написать код. Ваша большая идея — использовать XML для этого, и вы поспешно набросали свою идею на клочке бумаги и согласились с Питом …

1
2
3
4
5
6
<?xml version='1.0' encoding='UTF-8'?>
<pizza>
    <name>Capricciosa</name>
    <base>thin</base>
    <quantity>2</quantity>
</pizza>

Pete’s — очень маленькая компания, и вы в конечном итоге кодируете как конструктор сообщений на стойке регистрации, так и код парсера XML для кухни. Это ваша первая попытка XML и кода парсера кухни, который вы придумали:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class OrderPizza {
 
 
 
  private String pizzaName;
 
  private String base;
 
  private String quantity;
 
 
 
  public void order(String xmlOrder) {
 
 
 
    pizzaName = xmlOrder.substring(57, xmlOrder.indexOf('</', 58));
 
    int index = xmlOrder.indexOf('<base>', 58);
 
    int index2 = xmlOrder.indexOf('</', index);
 
    base = xmlOrder.substring(index + 6, index2);
 
    index = xmlOrder.indexOf('<quantity>', index2);
 
    index2 = xmlOrder.indexOf('</', index);
 
    quantity = xmlOrder.substring(index + 10, index2);
 
  }
 
 
 
  public String getPizzaName() {
 
    return pizzaName;
 
  }
 
 
 
  public String getBase() {
 
    return base;
 
  }
 
 
 
  public String getQuantity() {
 
    return quantity;
 
  }
 
}

… который очень хорошо работает в ваших юнит-тестах:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class OrderPizzaTest {
 
 
 
  private static final String ORDER_XML = //
 
  '<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n' + //
 
      '<pizza>\n' + //
 
      '    <name>Capricciosa</name>\n' + //
 
      '    <base>thin</base>\n' + //
 
      '    <quantity>2</quantity>\n' + //
 
      '</pizza>\n';
 
 
 
  private OrderPizza instance;
 
 
 
  @Before
 
  public void setUp() throws Exception {
 
 
 
    instance = new OrderPizza();
 
  }
 
 
 
  @Test
 
  public void readOrderFromXML() {
 
 
 
    instance.order(ORDER_XML);
 
 
 
    assertEquals('Capricciosa', instance.getPizzaName());
 
    assertEquals('thin', instance.getBase());
 
    assertEquals('2', instance.getQuantity());
 
  }
 
}

Это идет вживую и все хорошо ….

Время идет, и идеальная пицца Пита начинает расширяться. Приложение на стойке требует нескольких настроек, и Пит получает другого разработчика. Первое, что делает новый разработчик, — это решает, что было бы эффективнее избавиться от пробелов в XML-сообщении и отправил кухонному коду что-то вроде этого:

1
<?xml version='1.0' encoding='UTF-8'?><pizza><name>Capricciosa</name><base>thin</base><quantity>2</quantity></pizza>

Кухонный код мгновенно падает, и вы понимаете, что совершили первую и самую фундаментальную ошибку при работе с XML, то есть XML НЕ СТРОКА. XML — это объектно-ориентированная модель документа, которая может быть отображена с использованием строкового представления — урок, который многие люди усваивают сложным путем. И это не просто красивая печать строки, которая может сбить вас с толку, есть целая куча махинаций, форматирующих документы. Взять, к примеру, www.sitemaps.org. Этот веб-сайт определяет XML-схему, которая поддерживается Google, Yahoo !, и Microsoft, и позволяет веб-мастерам информировать поисковые системы о страницах на своих сайтах, доступных для сканирования с использованием XML-документа. Учитывая использование пространств имен в схеме, веб-сайт может возвращать что-то вроде этого, когда его просят о его карте сайта:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<?xml version='1.0' encoding='UTF-8'?>
   <url>
      <loc>http://www.example.com/</loc>
      <lastmod>2005-01-01</lastmod>
      <changefreq>monthly</changefreq>
      <priority>0.8</priority>
   </url>
   <url>
      <loc>http://www.example.com/page1/</loc>
      <lastmod>2006-01-02</lastmod>
      <changefreq>weekly</changefreq>
      <priority>0.8</priority>
   </url>
</urlset>

… но он мог бы в равной степени вернуть это:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<?xml version='1.0' encoding='UTF-8'?>
   <sm:url>
      <sm:loc>http://www.example.com/</sm:loc>
      <sm:lastmod>2005-01-01</sm:lastmod>
      <sm:changefreq>monthly</sm:changefreq>
      <sm:priority>0.8</sm:priority>
   </sm:url>
   <sm:url>
      <sm:loc>http://www.example.com/page1/</sm:loc>
      <sm:lastmod>2006-01-02</sm:lastmod>
      <sm:changefreq>weekly</sm:changefreq>
      <sm:priority>0.8</sm:priority>
   </sm:url>
</sm:urlset>

…или это:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<?xml version='1.0' encoding='UTF-8'?>
<sitemap:urlset xmlns:sitemap='http://www.sitemaps.org/schemas/sitemap/0.9'
   <sitemap:url>
      <sitemap:loc>http://www.example.com/</sitemap:loc>
      <sitemap:lastmod>2005-01-01</sitemap:lastmod>
      <sitemap:changefreq>monthly</sitemap:changefreq>
      <sitemap:priority>0.8</sitemap:priority>
   </sitemap:url>
   <sitemap:url>
      <sitemap:loc>http://www.example.com/page1/</sitemap:loc>
      <sitemap:lastmod>2006-01-02</sitemap:lastmod>
      <sitemap:changefreq>weekly</sitemap:changefreq>
      <sitemap:priority>0.8</sitemap:priority>
   </sitemap:url>
</sitemap:urlset>

… и все они действительны, эквивалентны и содержат одинаковую информацию. Это только их строковое представление, которые отличаются и взятые вместе, они подчеркивают первое правило XML, а именно XML НЕ СТРОКА.

Вернитесь к идеальной пицце Пита, и вы задаетесь вопросом, как вы можете исправить свой код, когда входит Пит и просит улучшения. Он хочет, чтобы вы улучшили систему, чтобы ваш XML-документ мог заказать более одной пиццы за раз. Вы понимаете, что манипулирование строками отсутствует и сталкиваетесь с SAX-анализом в Интернете, но об этом в другой раз.

1 Используя Google, вы обнаружите, что Pete’s Perfect Pizza со всего мира насчитывает четыре страницы. Эта история вымышленная, и любое сходство с любым из них является чисто совпадением.
2 Из прочтения XML-заказов вы можете догадаться, что моя любимая пицца — Capricciosa, и лучшая из всех, что когда-либо была доступна от Pizza Margherita

Исходный код доступен на GitHub по адресу:

мерзавец: //github.com/roghughe/captaindebug.git

Перейдите к части 2 серии.

Ссылка: Подходы к XML — Часть 1 — XML ​​не является строкой … от нашего партнера по JCG Роджера Хьюза из блога Captain Debug’s Blog .