たとえば、タグのフィールドをそのタグ内のタグに変換したい
<book name="Data Structure" price="250" pages="350"/>
に
<book name="Data Structure">
<price>250</price>
<pages>350</pages>
</book>
Xmlstarletまたはsedを使用してLinuxコマンドラインでこの操作を実行したい
process.xsl
:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="//book">
<xsl:element name="book">
<xsl:apply-templates select="./@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="book/@*">
<xsl:if test="name() = 'name'">
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:if>
<xsl:if test="name() != 'name'">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
input.xml
:
<book name="Data Structure" price="250" pages="350"/>
xsltproc process.xsl input.xml
<?xml version="1.0"?>
<book name="Data Structure">
<price>250</price>
<pages>350</pages>
</book>
お願いします-sed
を使用しないでください-それは仕事に適したツールではありません。
私は自分でPerlを使います:
_#!/usr/bin/env Perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->new( 'pretty_print' => 'indented_a' );
$twig->parsefile ( 'your_file.xml' );
foreach my $thing ( $twig -> root -> children ) {
my $newthing = $twig -> root -> insert_new_elt($thing->tag);
foreach my $key ( keys %{$thing -> atts()} ) {
$newthing -> insert_new_elt($key, $thing -> att($key));
}
$thing -> delete;
}
$twig->print;
_
出力:
_<root>
<book>
<pages>350</pages>
<name>Data Structure</name>
<price>250</price>
</book>
</root>
_
(匿名の)ハッシュatt()
を使用しているため、これは非常に簡単です。 1つの属性を選択するには、もう少し行う必要があります-実行することを定義する必要がありますkeepname
そして、それを親要素の属性として挿入します。
これはmap
を使用しますが、これは少し頭痛の種になる可能性があります。
_#!/usr/bin/env Perl
use strict;
use warnings;
use Data::Dumper;
use XML::Twig;
my %keep_att = ( name => 1 );
my $twig = XML::Twig->new( 'pretty_print' => 'indented_a' );
$twig->parse( \*DATA );
foreach my $thing ( $twig->root->children ) {
my $newthing = $twig->root->insert_new_elt( $thing->tag,
{ map { $_ => $thing->att($_) } keys %keep_att } );
foreach my $key ( keys %{ $thing->atts() } ) {
next if $keep_att{$key};
$newthing->insert_new_elt( $key, $thing->att($key) );
}
$thing->delete;
}
$twig->print;
__DATA__
<root>
<book name="Data Structure" price="250" pages="350"/>
</root>
_
これにより、次のものが生成されます。
_<root>
<book name="Data Structure">
<price>250</price>
<pages>350</pages>
</book>
</root>
_
さて、そのmap
で何が起こっているのかというと、基本的に保持したい属性を分割し、それらを新しい要素に再挿入し、要素を再挿入しますしない =維持し、子供に変えたい。
このようなビット:
_foreach my $thing ( $twig->root->children ) {
my %attributes = %{$thing->atts()};
my %new_children;
foreach my $attr ( keys %attributes ) {
if ( $keep_att{$attr} ) {
#leave it in %attributes;
}
else {
$new_children{$attr} = $attributes{$attr};
delete $attributes{$attr}
}
}
print Dumper \%attributes;
print Dumper \%new_children;
my $newthing = $twig->root->insert_new_elt( $thing->tag,
{ %attributes } );
foreach my $key ( keys %new_children ) {
$newthing->insert_new_elt( $key, $new_children{$key} );
}
$thing->delete;
}
_