Reputation: 7775
I have hundreds of xml files, which I want to do a one off edit to in a specific place. Somewhere in each xml file I have something that looks like this.
<SomeTag
attribute1 = "foo"
attribute2 = "bar"
attribute3 = "lol"/>
The number of attributes, and their names change depending on the file, but the SomeTag
doesn't. I'd like to add another attribute after the last attribute.
I realise editing xml this way is silly, but it is just a one off job which I'd like to do with something like sed
, but I can't figure out the multi-line usage.
Upvotes: 1
Views: 1978
Reputation: 241988
You can use XML shell xsh:
for my $file in { glob "*.xml" } {
open $file ;
for //SomeTag set @another 'new value' ;
save :b ;
}
Upvotes: 2
Reputation: 204035
If your input file is really that simple and consistently formatted:
$ cat file
foo
<SomeTag
attribute1 = "foo"
attribute2 = "bar"
attribute3 = "lol"/>
bar
$ gawk -v RS='\0' -v ORS= '{sub(/<SomeTag[^/]+/,"&\n attribute4 = \"eureka\"")}1' file
foo
<SomeTag
attribute1 = "foo"
attribute2 = "bar"
attribute3 = "lol"
attribute4 = "eureka"/>
bar
Upvotes: 1
Reputation: 6825
i would use a transformation stylesheet and an identity template (XSLT).
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="SomeTag">
<xsl:copy>
<xsl:attribute name="newAttribute">
<xsl:value-of select="'whatever'"/>
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
This will copy the entire XML, but will run through the defined template for your 'SomeTag'.
Taken from here
Upvotes: 3