Salgar
Salgar

Reputation: 7775

Mass XML Editing using command line tools

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

Answers (3)

choroba
choroba

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

Ed Morton
Ed Morton

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

mindandmedia
mindandmedia

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

Related Questions