ANT: заменить параметр в наборе файлов XML на основе содержимого файла XML - PullRequest
2 голосов
/ 21 августа 2011

У меня есть каталог с подкаталогами с XML-файлами в нем с различными расширениями.


Начало обновленной детали


Целевой каталог: /some/path

Маска целевых файлов: *.load

Базовый набор фильтров, который мы используем для поиска *.load файлов в /some/path:

<fileset dir="/some/path">
    <include name="**/*.load" />
</fileset>

Может быть несколько подкаталогов в /some/path и несколько файлов *.load.

Но нам нужно улучшить фильтрацию на основе содержимого XML и параметров, описанных в примерах, ниже приведены примеры использования.

Примеры:

load_file1.load:

<load 
    id="0a0740d1fc1a33a28f1397b76cae48bc"
    order="9"
    enable="true"
    name="Load name 1"
    type="LoadType.custom">
    <parent />
    <default-property name="Property2"
                      type="java.lang.Integer"
                      value="0" />
    <default-property name="Property1"
                      type="java.lang.Boolean"
                      value="false" />
</load>

load_file2.load:

<load 
      id="ec9ca08d11ca34b42e13c5f21578d82c"
      name="Load name 2"
      order="0"
      enable="true"
      type="LoadType.base">
    <parent />
    <default-property name="Load name 1"
                      type="java.lang.String"
                      value="test3" />
    <default-property name="Property2"
                      type="java.lang.Integer"
                      value="0" />
    <!-- here could be any number of other sub-properties  -->
    <date-range end-date="1/31/1900"
                     start-date="1/31/1900" />
</load>

Входные данные:

Параметр Ant: Load_name = "Load name 1" - используется для поиска соответствующих файлов

Параметр Ant: Load_param_name_replace = "enable"

Параметр Ant: Load_param_value_replace = "false"

Внимание!Мы всегда ищем файлы на основе значения атрибута //load/@name (жестко закодированного) внутри них:

<load 
      id="ec9ca08d11ca34b42e13c5f21578d82c"
      name="Load name 2"
      order="0"
      enable="true"
      type="LoadType.base">

Проблема (на основе примера файлов выше):

  1. Мы должны найти файлов , где //load/@name = $Load_name ANT param (" Имя загрузки 1 ")

  2. Мы должны изменить найденные файлы(может быть несколько) Атрибут XML объявлен в $Load_param_name_replace параметре ANT (" enable ") к значению параметра ANT $Load_param_value_replace (" false ")

Ожидаемые результаты :

  1. Найдено файлов: load_file1.load

NB! обратите внимание, что в load_file2.load у нас есть <default-property name="Load name 1" ..., которые соответствуют комбинации name="Load name 1", но мы должны различать этот недопустимый случай и действительный регистр в файле load_file1.load .

  1. В найденных файлах load_file1.load XML-атрибут, определенный в $Load_param_name_replace (" enable ")ANT параметр под //load узел должен быть изменен на новый value, определенный в ANT param $Load_param_value_replace (" false ")

Поэтому после задания ANT файл load_file1.load должен выглядеть так:

<load 
    id="0a0740d1fc1a33a28f1397b76cae48bc"
    order="9"
    enable="false"
    name="Load name 1"
    type="LoadType.custom">
    <parent />
    <default-property name="Property2"
                      type="java.lang.Integer"
                      value="0" />
    <default-property name="Property1"
                      type="java.lang.Boolean"
                      value="false" />
</load>

Конец обновленной части


Как видите, содержимое XML-файлов распределено по нескольким строкам - это сложная часть для меня.

Мы попробовали ANT fileset target с containsregexp фильтрами, где искали многострочное регулярное выражение с name="load_name1", но безуспешно.Мы использовали multiline=true и singleline=true - тоже не работали.

После этого мы попробовали XMLtask - но не было достаточно примеров того, как заменить свойство xml в нескольких файлах .XML на основе некоторого fileset.

Так что, если бы вы могли привести пару примеров - было бы здорово!

Ответы [ 2 ]

1 голос
/ 21 августа 2011

Полностью пересмотрено после обновления описания проблемы:

<project>
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask"/>

<property name="editno" value='&lt;default-property name="Load name 1"'/>
<property name="edityes" value='name="Load name 1"'/>
<property name="editxpath" value="//load/@enable"/>
<property name="editnew" value="false"/>

 <xmltask todir="/some/path" report="true">
  <fileset dir="/some/path">
   <include name="**/*.load"/>
    <not>
     <contains text="${editno}" casesensitive="true"/>
    </not>
    <contains text="${edityes}" casesensitive="true"/>
   </fileset>
   <replace path="${editxpath}" withText="${editnew}"/>
  </xmltask>
</project>

для быстрой проверки содержимого набора файлов просто используйте встроенное свойство $ {toString: filesetid}

 <fileset dir="/some/path" id="foobar">
  <include name="**/*.load" />
  <not>
   <contains text="${editno}" casesensitive="true" />
  </not>
  <contains text="${edityes}" casesensitive="true" />
 </fileset>

 <echo>${toString:foobar}</echo>

см. Руководство по Ant. Свойства и PropertyHelpers

1 голос
/ 21 августа 2011

Используйте задачу Ant XSLT, чтобы применить преобразование, как показано ниже:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="load[@name='load_name1']">
        <xsl:copy>
            <xsl:attribute name="from">date2</xsl:attribute>
            <xsl:apply-templates select="@*[name()!='from']"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Это создаст копию вашего ввода, заменив атрибут from на тегах, соответствующих name="load_name1".Обратите внимание, что это может изменить отступ, но будет работать независимо от того, как отформатирован ввод, что может быть невозможно при использовании регулярных выражений.

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