2015-06-30 2 views
0

Что такое преобразование XSLT (версия 1.0), которое может добавлять или заменять значения свойств на основе имени?XSLT для дополнения конфигурации Hadoop

К примеру, учитывая следующие входные XML

<configuration> 
    <property> 
     <name>dfs.replication</name> 
     <value>1</value> 
    </property> 

    <property> 
     <name>dfs.namenode.name.dir</name> 
     <value>/hadoop/dfs/name</value> 
    </property> 
</configuration> 

Как бы указать два свойства с именами и значениями, например:

<configuration> 
    <property> 
     <name>dfs.replication</name> 
     <value>2</value> 
    </property> 

    <property> 
     <name>dfs.datanode.data.dir</name> 
     <value>/hadoop/dfs/data</value> 
    </property> 
</configuration> 

Так полученный XML содержит все оригинальные детей из корень configuration элемент, и только один property с данным name? Например:

<configuration> 
    <property> 
     <name>dfs.replication</name> 
     <value>2</value> 
    </property> 

    <property> 
     <name>dfs.namenode.name.dir</name> 
     <value>/hadoop/dfs/name</value> 
    </property> 

    <property> 
     <name>dfs.datanode.data.dir</name> 
     <value>/hadoop/dfs/data</value> 
    </property> 
</configuration> 

Я попытался exampled от ряда других вопросов, но они не имеют ту же схему, и я не знаю, достаточно XSLT, чтобы приспособиться к моему прецеденту.

+0

Я не понимаю вашего вопроса. Почему исходное значение 'dfs.replication'' 1' изменилось на '2'? –

+0

@ michael.hor257k Целью является служить примером. Мой вопрос больше связан с возможностью вставки или изменения значений свойств на основе ключа. Я выбрал это конкретное имя свойства, например, для целей. благодаря! – maxwellb

+0

"* Я выбрал это конкретное имя свойства, например, для целей. *« Это имеет смысл, но пример не ясен (мне все равно). Вы говорите: «Итак, полученный XML содержит все исходные дети корневого элемента конфигурации *», но это не то, что вы показываете. –

ответ

1

Дано:

Входной XML

<configuration> 
    <property> 
     <name>A</name> 
     <value>old A</value> 
    </property> 
    <property> 
     <name>B</name> 
     <value>old B</value> 
    </property> 
</configuration> 

override.xml

<configuration> 
    <property> 
     <name>B</name> 
     <value>new B</value> 
    </property> 
    <property> 
     <name>C</name> 
     <value>new C</value> 
    </property> 
</configuration> 

следующая таблица стилей:

XSLT 1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="override-path" select="'override.xml'" /> 
<xsl:variable name="override-properties" select="document($override-path)/configuration/property" /> 

<xsl:template match="/configuration"> 
    <xsl:copy> 
     <!-- copy local properties not overridden by external properties --> 
     <xsl:copy-of select="property[not(name=$override-properties/name)]"/> 
     <!-- add all overiding properties --> 
     <xsl:copy-of select="$override-properties"/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

вернется:

<?xml version="1.0" encoding="UTF-8"?> 
<configuration> 
    <property> 
     <name>A</name> 
     <value>old A</value> 
    </property> 
    <property> 
     <name>B</name> 
     <value>new B</value> 
    </property> 
    <property> 
     <name>C</name> 
     <value>new C</value> 
    </property> 
</configuration> 
0

Это не ответ на вопрос, но я размещаю здесь как резолюцию для сообщества к проблеме, которую я пытался решить.

Я пытался создать минимально зависимые сценарии оболочки, которые могли бы обновить конфигурацию из Vagrantfile.

Этот ответ не затрагивает первоначальный вопрос, поэтому я не буду его принимать, но это то, с чем я столкнулся, тем временем.

Под каталогом provision, я создал следующую структуру:

provision/ 
|- hadoop/ 
| |- etc/ 
|  |- hadoop/ 
|   |- core-site.xml 
|   |- hdfs-site.xml 
|- lib/ 
| |- Provision/ 
|  |- Hadoop/ 
|   |- Override.pm 
|- hadoop-config.pl 

Где core-site.xml выглядит следующим образом:

<configuration> 
    <property> 
     <name>fs.defaultFS</name> 
     <value>hdfs://localhost:9000</value> 
    </property> 
</configuration> 

hdfs-site.xml похоже (голое форматирование),

И Override.pm является следующие:

use strict; 
use XML::LibXML; 
package Provision::Hadoop::Override; 

sub override_config 
{ 
    my ($xml, $override) = @_; 

    foreach my $property ($override->findnodes("/configuration/property")) 
    { 
     my $name = $property->find("name")->shift()->textContent; 
     my $value = $property->find("value")->shift()->textContent; 

     if (my($node) = $xml->findnodes("/configuration/property[name='$name']")) 
     { 
      if (my($vnode) = $xml->findnodes("/configuration/property[name='$name']/value")) 
      { 
       $vnode->removeChildNodes(); 
       $vnode->appendText($value); 
      } 
     } 
     else 
     { 
      my $config = $xml->find("/configuration")->shift(); 
      my $prop = $config->addNewChild(undef, "property"); 
      $prop->appendText("\n\t"); 
      $prop->addNewChild(undef, "name")->appendText($name); 
      $prop->appendText("\n\t"); 
      $prop->addNewChild(undef, "value")->appendText($value); 
      $prop->appendText("\n"); 
      $config->addChild($prop); 
      $config->appendText("\n"); 
     } 
    } 
    $xml; 
} 

1; 

С hadoop-config.pl слева, как, например:

#!/usr/bin/perl -- 
use lib "/vagrant/provision/lib"; 
use Provision::Hadoop::Override; 
use File::Find; 
use XML::LibXML; 

sub process_file { 
    if (-f $_) 
    { 
     my $dirname = "/vagrant/provision/hadoop"; 
     my $hadoop_prefix = $ENV{HADOOP_PREFIX}; 
     my $config = $File::Find::name; 
     my $override = XML::LibXML->load_xml(location => $config); 
     print "Loading values from $config"; 
     $config =~ s/$dirname/$hadoop_prefix/; 
     print " into $config..."; 
     my $xml = XML::LibXML->load_xml(location => $config); 

     Provision::Hadoop::Override::override_config($xml, $override); 

     $xml->toFile($config); 
     print " OK.\n"; 
    } 
} 
find(\&process_file, ("/vagrant/provision/hadoop")); 
Смежные вопросы