Использование регулярных выражений для исправления содержимого XML - PullRequest
0 голосов
/ 28 апреля 2009

Я пытаюсь исправить некоторые двуязычные XML-файлы, используя регулярные выражения, чтобы соответствовать известным образцам ошибочного содержимого и подставляя правильные значения. Большинство проблем в файлах xml можно считать опечатками или избыточными данными.

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

#!/bin/sed -f
s/<prop type="Att::Status">New/<prop type="Att::Status">Not Validated/g
s/<prop type="Att::Status">Approved/<prop type="Att::Status">Validated/g
....

Я обнаружил, что sed не очень-то нравятся файлы UTF16, и, поскольку мы имеем дело с двуязычным xml в 34 различных языковых комбинациях, было бы очень опасно использовать такой инструмент, как iconv, чтобы обернуть вокруг сценария sed. Большинство инструментов преобразования кодировок приводят к некоторому повреждению, и я бы предпочел не тратить оставшуюся часть недели на то, чтобы решить, на каких языках скрипт работает правильно.

Стоит также упомянуть, что xml полон накопленных переводов клиента за последние несколько лет, поэтому в нем будет много неправильно сформированного синтаксиса, который может привести к отключению некоторых инструментов.

Итак, в общем, sed + iconv слишком рискован, у меня есть базовый инструмент для глобальной замены текста, у меня есть Notepad ++, у меня даже есть список выражений для замены в синтаксисе sed. Но есть ли более легкий / лучший способ?

Ответы [ 3 ]

1 голос
/ 28 апреля 2009

См. XMLStarlet . Это набор инструментов командной строки для чтения / манипулирования XML.

В частности, команда xml ed , вероятно, то, что вы хотите. Вы можете указать XPath, что вы хотите изменить, и как это изменить. Он будет учитывать указанную кодировку символов XML и т. Д., Что не будут ваши стандартные инструменты командной строки.

1 голос
/ 29 апреля 2009

Я не знаю, меньше ли сложности XML Starlet, чем сложности XSLT - большая часть сложности на самом деле находится в XPath, который вы собираетесь использовать для поиска узлов, которые вы собираетесь изменить .

Если бы вы использовали XSLT, вы просто создали бы преобразование идентичности, а затем добавили шаблон для изменения интересующих вас текстовых узлов:

<xsl:template match="prop[@type='Att::Status']/text()">
   <xsl:choose>
      <xsl:when test=". = 'New'">Validated</xsl:when>
      <xsl:when test=". = 'Approved'">Not Validated</xsl:when>
      <xsl:otherwise>
         <xsl:copy/>
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>

Или вы можете сходить с ума и указать отображение во внешнем XML-файле, например ::

<map>
   <text value="New">Validated</text>
   <text value="Approved">Not Validated</text>
</map>

Тогда в вашем XSLT:

<xsl:variable name="map" select="document('map.xml')/map/text"/>

<xsl:template match="prop[@type='Att::Status']/text()">
   <xsl:choose>
      <xsl:when test="$map[@value=current()]">
         <xsl:copy-of select="$map[@value=current()]/text()"/>
      </xsl:when>
      <xsl:otherwise>
         <xsl:copy/>
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>
0 голосов
/ 28 апреля 2009

Я бы подумал, что xslt - ваш лучший выбор для подобных вещей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...