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