Статьи

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

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

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

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

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

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;
  }
}

...which works really well in your unit tests:
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-сообщении и отправил кухонному коду что-то вроде этого:

<?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-документа. Учитывая использование пространств имен в схеме, веб-сайт может возвращать что-то вроде этого, когда его просят о его карте сайта:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
   <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> 

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

<?xml version="1.0" encoding="UTF-8"?>
<sm:urlset xmlns:sm="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
   <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>

…или это:

<?xml version="1.0" encoding="UTF-8"?>
<sitemap:urlset xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
   <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

 

С http://www.captaindebug.com/2012/01/approaches-to-xml-part-1-xml-is-not.html