Я работал над приложением Geo. Со временем XML продукта стал немного грязным. Проблема возникает при синхронизации изменений в нескольких средах, таких как Dev, Test и т. Д. Я пытаюсь найти способ нормализации содержимого, чтобы избежать трудоемких действий при редактировании и слиянии, и, следовательно, получить продуктивную разработку. , Я знаю, это звучит безумно, и на заднем плане многое, но позвольте мне перейти к актуальной проблеме, оставив историю.
Вот проблема:
Применено несколько заказов на сортировку, например:
- Сортировка по обратному доменному имени. Например, для сортировки следует читать
d.c.b.a
как a.b.c.d
или map.google.com
как com.google.map
.
- Если домен содержит не алфавитно-цифровые символы, такие как *,?, [,] И т. Д., Тогда этот узел должен быть после определенного, так как область действия широка.
- Сортировка по порту и пути как 2-ая последующая сортировка.
- Применить аналогичный порядок сортировки для тегов в элементе
<tgt>
, если имеется.
- Удалите теги
<scheme>
и <port>
, когда значения являются общими, например, http / https для тега схемы и 80 или 443 для тега порта, в противном случае сохраните. Кроме того, удалите, если нет значения, например <scheme/>
.
- Сохранить все остальные теги и значения как есть.
- Тривиальная вещь, такая как отступ от 2 пробелов и фактические данные, не требуя шаблонного материала.
Вот немного проблемного XML:
XML
<?xml version='1.0' encoding='UTF-8' ?>
<?tapia chrome-version='2.0' ?>
<mapGeo>
<a>blah</a>
<b>blah</b>
<maps>
<mapIndividual>
<src>
<scheme>https</scheme>
<domain>photos.yahoo.com</domain>
<path>somepath</path>
<query>blah</query>
</src>
<loc>C:\var\tmp</loc>
<x>blah</x>
<y>blah</y>
</mapIndividual>
<mapIndividual>
<src>
<scheme>tcp</scheme>
<domain>map.google.com</domain>
<port>80</port>
<path>/value</path>
<query>blah</query>
</src>
<tgt>
<scheme>https</scheme>
<domain>map.google.com</domain>
<port>443</port>
<path>/value</path>
<query>blah</query>
</tgt>
<x>blah</x>
<y>blah</y>
</mapIndividual>
<mapIndividual>
<src>
<scheme>http</scheme>
<domain>*.c.b.a</domain>
<path>somepath</path>
<port>8085</port>
<query>blah</query>
</src>
<tgt>
<domain>r.q.p</domain>
<path>somepath</path>
<query>blah</query>
</tgt>
<x>blah</x>
<y>blah</y>
</mapIndividual>
<mapIndividual>
<src>
<scheme>http</scheme>
<domain>d.c.b.a</domain>
<path>somepath</path>
<port>8085</port>
<query>blah</query>
</src>
<tgt>
<domain>r.q.p</domain>
<path>somepath</path>
<query>blah</query>
</tgt>
<x>blah</x>
<y>blah</y>
</mapIndividual>
<maps>
</mapGeo>
Мне удалось применить базовую сортировку значений как есть, но я не смог найти способ генерирования обратного доменного имени. Я столкнулся с расширением XSL, но еще не пробовал. Вот начальная часть решения, над которым я работал, оно очень простое.
XSL
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="maps">
<xsl:copy>
<xsl:apply-templates select="*">
<xsl:sort select="src/domain" />
<xsl:sort select="src/port" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Ожидаемый результат
<?xml version='1.0' encoding='UTF-8' ?>
<?tapia chrome-version='2.0' ?>
<mapGeo>
<a>blah</a>
<b>blah</b>
<maps>
<mapIndividual>
<src>
<domain>d.c.b.a</domain>
<path>somepath</path>
<port>8085</port>
<query>blah</query>
</src>
<tgt>
<domain>r.q.p</domain>
<path>somepath</path>
<query>blah</query>
</tgt>
<x>blah</x>
<y>blah</y>
</mapIndividual>
<mapIndividual>
<src>
<domain>*.c.b.a</domain>
<path>path1</path>
<port>8085</port>
<query>blah</query>
</src>
<tgt>
<domain>r.q.p</domain>
<path>path2</path>
<query>blah</query>
</tgt>
<x>blah</x>
<y>blah</y>
</mapIndividual>
<mapIndividual>
<src>
<scheme>tcp</scheme>
<domain>map.google.com</domain>
<path>/value</path>
<query>blah</query>
</src>
<tgt>
<domain>map.google.com</domain>
<path>/value</path>
<query>blah</query>
</tgt>
<x>blah</x>
<y>blah</y>
</mapIndividual>
<mapIndividual>
<src>
<domain>photos.yahoo.com</domain>
<path>somepath</path>
<query>blah</query>
</src>
<loc>C:\var\tmp</loc>
<x>blah</x>
<y>blah</y>
</mapIndividual>
<maps>
</mapGeo>
Примечание. Я бы предпочел XSLT 1.0, поскольку он поддерживается в текущей среде. XSLT 2.0 будет плюсом.
Обновление: я нашел решение для поддержки XSLT 2.0 и XSLT 3.0, поэтому, пожалуйста, игнорируйте мою предыдущую заметку для XSLT 1.0.
Заранее спасибо!
Приветствия