Home > Mobile >  How to alter 2 subelements of xml file in python by their tag parameter using ElementTree?
How to alter 2 subelements of xml file in python by their tag parameter using ElementTree?

Time:04-22

I have an xml file like this, I want to alter the 2 sub-elements.

I tried like below.

import xml.etree.ElementTree as ET

file_name = 'manifest.mpd'
tree = ET.parse(file_name)
root = tree.getroot()

for elem in root:
    for subelem in elem:
        a = subelem.attrib
        if a['mimeType'] == 'audio/mp4':
            if subelem.get('lang') == 'bg':
                source_elem = subelem
                break

for elem in root:
    for subelem in elem:
        d = subelem.attrib
        if d['mimeType'] == 'audio/mp4':
            if (subelem.get('lang') == 'tr'):
                subelem = source_elem

tree.write('output.mpd')

Below is my xml file.

      <?xml version="1.0" ?>
      <MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT4.80S" mediaPresentationDuration="PT44M19.080S" type="static">
        <Period>
          <AdaptationSet mimeType="video/mp4" segmentAlignment="true" startWithSAP="1" maxWidth="1920" maxHeight="1080">
            <SegmentTemplate timescale="1000" duration="4800" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
            <Representation id="video/avc1/1" codecs="avc1.64001E" width="640" height="360" scanType="progressive" frameRate="25" bandwidth="798779"/>
            <Representation id="video/avc1/2" codecs="avc1.640028" width="1920" height="1080" scanType="progressive" frameRate="25" bandwidth="4107000"/>
            <Representation id="video/avc1/3" codecs="avc1.64001E" width="848" height="480" scanType="progressive" frameRate="25" bandwidth="1498236"/>
            <Representation id="video/avc1/4" codecs="avc1.64001F" width="1280" height="720" scanType="progressive" frameRate="25" bandwidth="2497736"/>
          </AdaptationSet>
          <AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true" lang="en">
            <SegmentTemplate timescale="1000" duration="2000" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
            <Representation id="audio/en/mp4a.40.2" codecs="mp4a.40.2" bandwidth="131529" audioSamplingRate="48000">
              <AudioChannelConfiguration schemeIdUri="urn:mpeg:mpegB:cicp:ChannelConfiguration" value="2"/>
            </Representation>
          </AdaptationSet>
          <AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true" lang="tr">
            <SegmentTemplate timescale="1000" duration="4800" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
            <Representation id="audio/tr/mp4a.40.2" codecs="mp4a.40.2" bandwidth="127472" audioSamplingRate="44100">
              <AudioChannelConfiguration schemeIdUri="urn:mpeg:mpegB:cicp:ChannelConfiguration" value="2"/>
            </Representation>
          </AdaptationSet>
          <AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true" lang="ru">
            <SegmentTemplate timescale="1000" duration="2000" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
            <Representation id="audio/ru/mp4a.40.2" codecs="mp4a.40.2" bandwidth="129917" audioSamplingRate="48000">
              <AudioChannelConfiguration schemeIdUri="urn:mpeg:mpegB:cicp:ChannelConfiguration" value="2"/>
            </Representation>
          </AdaptationSet>
          <AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true" lang="bg">
            <SegmentTemplate timescale="1000" duration="2000" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
            <Representation id="audio/bg/mp4a.40.2" codecs="mp4a.40.2" bandwidth="135019" audioSamplingRate="48000">
              <AudioChannelConfiguration schemeIdUri="urn:mpeg:mpegB:cicp:ChannelConfiguration" value="2"/>
            </Representation>
          </AdaptationSet>
          <AdaptationSet mimeType="text/vtt" contentType="text" lang="en">
            <Role schemeIdUri="urn:mpeg:dash:role:2011" value="subtitle"/>
            <Representation id="subtitles/en" bandwidth="141">
              <BaseURL>subtitles/en/TDCS00187_SPY001285-00001ENG.vtt</BaseURL>
            </Representation>
          </AdaptationSet>
          <AdaptationSet mimeType="text/vtt" contentType="text" lang="sr">
            <Role schemeIdUri="urn:mpeg:dash:role:2011" value="subtitle"/>
            <Representation id="subtitles/sr" bandwidth="130">
              <BaseURL>subtitles/sr/TDCS00187_SPY001285-00001SRB.vtt</BaseURL>
            </Representation>
          </AdaptationSet>
          <AdaptationSet mimeType="text/vtt" contentType="text" lang="hr">
            <Role schemeIdUri="urn:mpeg:dash:role:2011" value="subtitle"/>
            <Representation id="subtitles/hr" bandwidth="132">
              <BaseURL>subtitles/hr/TDCS00187_SPY001285-00001CRO.vtt</BaseURL>
            </Representation>
          </AdaptationSet>
          <AdaptationSet mimeType="text/vtt" contentType="text" lang="sq">
            <Role schemeIdUri="urn:mpeg:dash:role:2011" value="subtitle"/>
            <Representation id="subtitles/sq" bandwidth="139">
              <BaseURL>subtitles/sq/TDCS00187_SPY001285-00001ALB.vtt</BaseURL>
            </Representation>
          </AdaptationSet>
        </Period>
      </MPD>

I want to alter the below complete node(first audio type node)

<AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true" lang="en">
  <SegmentTemplate timescale="1000" duration="2000" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
  <Representation id="audio/en/mp4a.40.2" codecs="mp4a.40.2" bandwidth="131529" audioSamplingRate="48000">
    <AudioChannelConfiguration schemeIdUri="urn:mpeg:mpegB:cicp:ChannelConfiguration" value="2"/>
  </Representation>
</AdaptationSet>

with it's any other node(audio type node)

<AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true" lang="tr">
  <SegmentTemplate timescale="1000" duration="4800" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
  <Representation id="audio/tr/mp4a.40.2" codecs="mp4a.40.2" bandwidth="127472" audioSamplingRate="44100">
    <AudioChannelConfiguration schemeIdUri="urn:mpeg:mpegB:cicp:ChannelConfiguration" value="2"/>
  </Representation>
</AdaptationSet>

And save this content into a new xml file.

Is there any methods to replace nodes?

I tried by searching the nodes with their 'lang' parameter, but I couldn't get it.

To be clearly Any audio node has to be replaced(shifted/altered) with audio node.

e.g. I want the node which is having the lang="bg" to be shifted with the node which is having the lang="en".

Any help would be appreciate. Thanks in advance.

CodePudding user response:

Assuming that you want to order the languages in a custom (speak: different) order, you can use an XSLT-1.0 stylesheet that can be processed by any XSLT-1.0 capable processor (like xsltproc, Saxon, Xalan and others).

It could look like this (using the lang tags as criteria for ordering):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:mpeg="urn:mpeg:dash:schema:mpd:2011">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="mpeg:AdaptationSet[@mimeType='audio/mp4'][1]">
    <xsl:copy-of select="../mpeg:AdaptationSet[@mimeType='audio/mp4'][@lang='bg']" />
    <xsl:copy-of select="../mpeg:AdaptationSet[@mimeType='audio/mp4'][@lang='en']" />
    <xsl:copy-of select="../mpeg:AdaptationSet[@mimeType='audio/mp4'][@lang='ru']" />
    <xsl:copy-of select="../mpeg:AdaptationSet[@mimeType='audio/mp4'][@lang='tr']" />
  </xsl:template>

  <xsl:template match="mpeg:AdaptationSet[@mimeType='audio/mp4'][position() > 1]" />
      
</xsl:stylesheet>

Its output is:

<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT4.80S" mediaPresentationDuration="PT44M19.080S" type="static">
    <Period>
        <AdaptationSet mimeType="video/mp4" segmentAlignment="true" startWithSAP="1" maxWidth="1920" maxHeight="1080">
            <SegmentTemplate timescale="1000" duration="4800" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
            <Representation id="video/avc1/1" codecs="avc1.64001E" width="640" height="360" scanType="progressive" frameRate="25" bandwidth="798779"/>
            <Representation id="video/avc1/2" codecs="avc1.640028" width="1920" height="1080" scanType="progressive" frameRate="25" bandwidth="4107000"/>
            <Representation id="video/avc1/3" codecs="avc1.64001E" width="848" height="480" scanType="progressive" frameRate="25" bandwidth="1498236"/>
            <Representation id="video/avc1/4" codecs="avc1.64001F" width="1280" height="720" scanType="progressive" frameRate="25" bandwidth="2497736"/>
        </AdaptationSet>
        <AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true" lang="bg">
            <SegmentTemplate timescale="1000" duration="2000" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
            <Representation id="audio/bg/mp4a.40.2" codecs="mp4a.40.2" bandwidth="135019" audioSamplingRate="48000">
                <AudioChannelConfiguration schemeIdUri="urn:mpeg:mpegB:cicp:ChannelConfiguration" value="2"/>
            </Representation>
        </AdaptationSet>
        <AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true" lang="en">
            <SegmentTemplate timescale="1000" duration="2000" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
            <Representation id="audio/en/mp4a.40.2" codecs="mp4a.40.2" bandwidth="131529" audioSamplingRate="48000">
                <AudioChannelConfiguration schemeIdUri="urn:mpeg:mpegB:cicp:ChannelConfiguration" value="2"/>
            </Representation>
        </AdaptationSet>
        <AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true" lang="ru">
            <SegmentTemplate timescale="1000" duration="2000" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
            <Representation id="audio/ru/mp4a.40.2" codecs="mp4a.40.2" bandwidth="129917" audioSamplingRate="48000">
                <AudioChannelConfiguration schemeIdUri="urn:mpeg:mpegB:cicp:ChannelConfiguration" value="2"/>
            </Representation>
        </AdaptationSet>
        <AdaptationSet mimeType="audio/mp4" startWithSAP="1" segmentAlignment="true" lang="tr">
            <SegmentTemplate timescale="1000" duration="4800" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1"/>
            <Representation id="audio/tr/mp4a.40.2" codecs="mp4a.40.2" bandwidth="127472" audioSamplingRate="44100">
                <AudioChannelConfiguration schemeIdUri="urn:mpeg:mpegB:cicp:ChannelConfiguration" value="2"/>
            </Representation>
        </AdaptationSet>
        
        
        
        <AdaptationSet mimeType="text/vtt" contentType="text" lang="en">
            <Role schemeIdUri="urn:mpeg:dash:role:2011" value="subtitle"/>
            <Representation id="subtitles/en" bandwidth="141">
                <BaseURL>subtitles/en/TDCS00187_SPY001285-00001ENG.vtt</BaseURL>
            </Representation>
        </AdaptationSet>
        <AdaptationSet mimeType="text/vtt" contentType="text" lang="sr">
            <Role schemeIdUri="urn:mpeg:dash:role:2011" value="subtitle"/>
            <Representation id="subtitles/sr" bandwidth="130">
                <BaseURL>subtitles/sr/TDCS00187_SPY001285-00001SRB.vtt</BaseURL>
            </Representation>
        </AdaptationSet>
        <AdaptationSet mimeType="text/vtt" contentType="text" lang="hr">
            <Role schemeIdUri="urn:mpeg:dash:role:2011" value="subtitle"/>
            <Representation id="subtitles/hr" bandwidth="132">
                <BaseURL>subtitles/hr/TDCS00187_SPY001285-00001CRO.vtt</BaseURL>
            </Representation>
        </AdaptationSet>
        <AdaptationSet mimeType="text/vtt" contentType="text" lang="sq">
            <Role schemeIdUri="urn:mpeg:dash:role:2011" value="subtitle"/>
            <Representation id="subtitles/sq" bandwidth="139">
                <BaseURL>subtitles/sq/TDCS00187_SPY001285-00001ALB.vtt</BaseURL>
            </Representation>
        </AdaptationSet>
    </Period>
</MPD>apply-templates

You can call this XSLT from Python like described in this answer. Pay attention to the fact that other languages than the ones being copied are ignored without notice.

CodePudding user response:

I recommend you having a look at The ElementTree XML API in Python: link

I've used it in the past to parse really large XML files (over 1gb) and it was one of the fastest solutions that I've found.

  • Related