扩展Hadoop配置的XSLT
什么是可以根据名称添加或替换属性值的XSLT(1.0版)转换 例如,给定以下输入XML扩展Hadoop配置的XSLT,xslt,Xslt,什么是可以根据名称添加或替换属性值的XSLT(1.0版)转换 例如,给定以下输入XML <configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.namenode.
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/hadoop/dfs/name</value>
</property>
</configuration>
我试过其他几个问题的例子,但它们没有相同的模式,我也不知道足够多的XSLT来适应我的用例。这不是问题的答案,但我在这里发布,作为社区对我试图解决的问题的解决方案 我试图创建最小依赖的shell脚本,可以从一个文件更新配置 这个答案并没有解决最初的问题,所以我不会接受它,但这正是我在这段时间里最终要回答的问题 在
供应
目录下,我创建了以下结构:
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>
在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"));
鉴于:
输入XML
<configuration>
<property>
<name>A</name>
<value>old A</value>
</property>
<property>
<name>B</name>
<value>old B</value>
</property>
</configuration>
A.
老A
B
老B
override.xml
<configuration>
<property>
<name>B</name>
<value>new B</value>
</property>
<property>
<name>C</name>
<value>new C</value>
</property>
</configuration>
B
新B
C
新C
以下样式表:
XSLT1.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>
A.
老A
B
新B
C
新C
我不明白你的问题。为什么1
的原始dfs.replication
值更改为2
?@michael.hor257k目的是作为示例。我的问题更多地涉及基于键插入或更改属性值的能力。我选择了那个特定的属性名称作为示例。谢谢“我选择那个特定的属性名称是为了举例。”这是有道理的,但这个例子(对我来说)并不清楚。您会说“因此生成的XML包含根配置元素的所有原始子元素”,但这不是您所显示的。@michael.hor257k我希望您能提供任何关于如何使其更清晰的建议。我的意思是,如果输入包含名为A和B的属性,并且转换为转换指定名为B和C的属性,那么输出包含名为A、B和C的属性。此外,属性B的值包含来自转换的值(而不是输入),但是A的值保持不变。您是希望在样式表中硬编码“转换属性”,还是希望将其存储在外部XML文档中?
<configuration>
<property>
<name>B</name>
<value>new B</value>
</property>
<property>
<name>C</name>
<value>new C</value>
</property>
</configuration>
<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>