Как я могу изменить значение параметра в XML с помощью Perl? - PullRequest
0 голосов
/ 04 августа 2010

Мой XML-файл выглядит так:

<Configuration>
    <Parameters>
        <Component Name="Aas">
            <Group Name="PrivilegesMapping">
                <Parameter Name="PrivilegesLoaderInterval">
                    <Description>
                    The interval (in minute) 
                    </Description>
                    <Type>Integer</Type>
                    <Restriction>
                        <RequiresRestart>true</RequiresRestart>
                        <MinVal/>
                        <MaxVal/>
                        <MaxLength/>
                        <Mandatory>true</Mandatory>
                        <Lov/>
                        <Level>5</Level>
                    </Restriction>
                    <Value>
                        <Item Value="5"/>
                    </Value>
                </Parameter>
            </Group>
            <Group Name="DomainsMapping">
                <Parameter Name="DomainLoaderInterval">
                    <Description>
                    The interval (in minute) 
                    </Description>
                    <Type>Integer</Type>
                    <Restriction>
                        <RequiresRestart>true</RequiresRestart>
                        <MinVal/>
                        <MaxVal/>
                        <MaxLength/>
                        <Mandatory>true</Mandatory>
                        <Lov/>
                        <Level>5</Level>
                    </Restriction>
                    <Value>
                        <Item Value="5"/>
                    </Value>
                </Parameter>
                <Parameter Name="MapSource">
                    <Description>
                    Set the source of the domains list
                    </Description>
                    <Type>Enum</Type>
                    <Restriction>
                        <RequiresRestart>true</RequiresRestart>
                        <MinVal/>
                        <MaxVal/>
                        <MaxLength/>
                        <Mandatory>true</Mandatory>
                        <Lov>
                            <Val>FILE</Val>
                            <Val>DATABASE</Val>
                            <Val>NONE</Val>
                        </Lov>
                        <Level>5</Level>
                    </Restriction>
                    <Value>
                        <Item Value="FILE"/>
                    </Value>
                </Parameter>
            </Group>
            <Group Name="SystemsMapping">
                <Parameter Name="MapSource">
                    <Description>
                    </Description>
                    <Type>Enum</Type>
                    <Restriction>
                        <RequiresRestart>true</RequiresRestart>
                        <MinVal/>
                        <MaxVal/>
                        <MaxLength/>
                        <Mandatory>true</Mandatory>
                        <Lov>
                            <Val>API</Val>
                            <Val>FILE</Val>
                            <val>NONE</Val>
                        </Lov>
                        <Level>5</Level>
                    </Restriction>
                    <Value>
                        <Item Value="NONE"/>
                    </Value>
                </Parameter>
                <Parameter Name="SystemsLoaderInterval">
                    <Description>
                    The interval (in minute) 
                    </Description>
                    <Type>Integer</Type>
                    <Restriction>
                        <RequiresRestart>true</RequiresRestart>
                        <MinVal/>
                        <MaxVal/>
                        <MaxLength/>
                        <Mandatory>true</Mandatory>
                        <Lov/>
                        <Level>5</Level>
                    </Restriction>
                    <Value>
                        <Item Value="5"/>
                    </Value>
                </Parameter>
            </Group>
        </Component>
    </Parameters>
</Configuration>

Я бы хотел изменить значение с <Item Value="NONE"/> на <Item Value="API"/> в <Parameter Name="MapSource">.

Ответы [ 2 ]

0 голосов
/ 04 августа 2010

Самый быстрый (самый простой) способ, который я нашел, был XML::XPath (еще меньше с File::Slurp - см. Историю изменений для кода преднаборной обработки):

use strict;
use warnings;
use File::Slurp ();
use XML::XPath;
use XML::XPath::XMLParser;

my $path = '/path/to/file/config.xml';
my $xp   = XML::XPath->new( filename => $path );
$xp->setNodeText( q{//Parameter[@Name='MapSource']/Value/Item/@Value} 
                , 'API'
                );
File::Slurp::write_file( $path, $xp->findnodes_as_string( '/' ));
0 голосов
/ 04 августа 2010

Помните, что обработка XML с помощью регулярных выражений - это обычно очень плохая идея , с Perl вы можете

#! /usr/bin/perl

use warnings;
use strict;

system("xsltproc", "fix.xsl", "input.xml") == 0
  or warn "$0: xsltproc failed\n";

и с fix.xsl из

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

  <xsl:template match="/Configuration/Parameters/Component/Group/Parameter[@Name='MapSource']/Value/Item[@Value='NONE']">
    <xsl:element name="Item">
      <xsl:attribute name="Value">API</xsl:attribute>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

чтобы получить желаемый результат:

$ diff -ub input.xml <(./prog.pl)
--- input.xml
+++ /dev/fd/63
@@ -1,3 +1,4 @@
+<?xml version="1.0"?>
 <Configuration>
     <Parameters>
         <Component Name="Aas">
@@ -82,7 +83,7 @@
                         <Level>5</Level>
                     </Restriction>
                     <Value>
-                        <Item Value="NONE"/>
+                        <Item Value="API"/>
                     </Value>
                 </Parameter>
                 <Parameter Name="SystemsLoaderInterval">

Если вы не знакомы, <(./prog.pl) использует подстановка процесса bash , поэтому команда diff сравнивает input.xml с вывод короткой Perl-программы.

Чтобы заменить все элементы Item, которые являются потомками параметров MapSource, используйте таблицу стилей ниже.Обратите внимание, как она более гибка в отношении структуры исходного документа.

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

  <xsl:template match="//Parameter[@Name='MapSource']//Item">
    <xsl:element name="Item">
      <xsl:attribute name="Value">API</xsl:attribute>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

Теперь переход от ввода к выводу составляет

$ diff -ub input.xml <(./prog.pl)
--- input.xml
+++ /dev/fd/63
@@ -1,3 +1,4 @@
+<?xml version="1.0"?>
 <Configuration>
     <Parameters>
         <Component Name="Aas">
@@ -59,7 +60,7 @@
                         <Level>5</Level>
                     </Restriction>
                     <Value>
-                        <Item Value="FILE"/>
+                        <Item Value="API"/>
                     </Value>
                 </Parameter>
             </Group>
@@ -82,7 +83,7 @@
                         <Level>5</Level>
                     </Restriction>
                     <Value>
-                        <Item Value="NONE"/>
+                        <Item Value="API"/>
                     </Value>
                 </Parameter>
                 <Parameter Name="SystemsLoaderInterval">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...