I'm new using xmlstarlet. I'd like to know how to change the value of xml node using xmlstarlet.
I tried something.
xmlstarlet ed --inplace -u '/file_input/uri' 'string("s3://my_source")' template.xml > output.xml
doesn't work.
My expected output as s3://my_source and s3://mydestination. I'd like to change source_path and destination_path node.
<?xml version="1.0" encoding="UTF-8"?>
<job version="2.10.8">
<input>
<deblock_enable>Auto</deblock_enable>
<deblock_strength>0</deblock_strength>
<no_psi>false</no_psi>
<order>1</order>
<timecode_source>zerobased</timecode_source>
<file_input>
<certificate_file nil="true"/>
<password>upass</password>
<uri>source_path</uri>
<username>uname</username>
</file_input>
<file_group_settings>
<rollover_interval nil="true"/>
<destination>
<password>upass</password>
<username>uname</username>
<uri>destination_path</uri>
</destination>
</file_group_settings>
</input>
</job>
Thank you very much
With xmlstarlet:
xmlstarlet edit \
--update "//job/input/file_input/uri" \
--value 's3://my_source' \
--update "//job/input/file_group_settings/destination/uri" \
--value 's3://mydestination' file.xml
If you want to edit file.xml inplace, add option -L.
See: xmlstarlet edit --help
Related
I would like to select and change a value in an XML file. I'm trying to use xmlstarlet for this.
I have this file
<?xml version='1.0' encoding='UTF-8'?>
<DeviceDescription xmlns="http://www.3s-software.com/schemas/DeviceDescription-1.0.xsd">
<House>
<Id>
<Number>1</Number>
</Id>
</House>
<Car>
<Id>
<Number>2</Number>
</Id>
</Car>
</DeviceDescription>
My problem is the xmlns= field which xmlstarlet is picky about. Without this field I can use
xmlstarlet sel -t -v '/Description/House/Id/Number' /tmp/x.xml
I found that I can use a default namespace like this, but that returns both Id's
xmlstarlet sel -t -m "//_:Id" -v '_:Number' /tmp/x.xml
How do I specify a full path?
To only match the House id, add it to the -m argument:
xml sel -t -m '//_:House/_:Id' -v '_:Number'
If you want to use the namespace, specify it with -N, e.g.:
xml sel -N ns="http://www.3s-software.com/schemas/DeviceDescription-1.0.xsd" \
-t -v 'ns:DeviceDescription/ns:House/ns:Id/ns:Number'
So to update the value:
xml ed -N ns="http://www.3s-software.com/schemas/DeviceDescription-1.0.xsd" \
-u 'ns:DeviceDescription/ns:House/ns:Id/ns:Number' -v 3
Output:
<?xml version="1.0" encoding="UTF-8"?>
<DeviceDescription xmlns="http://www.3s-software.com/schemas/DeviceDescription-1.0.xsd">
<House>
<Id>
<Number>3</Number>
</Id>
</House>
<Car>
<Id>
<Number>2</Number>
</Id>
</Car>
</DeviceDescription>
I'm using media info, to get some xml information about movie:
mediainfo --Output=XML Krtek\ a\ buldozer-jdvwqZUEbhc.mkv | xmlstarlet format
which output is:
<?xml version="1.0" encoding="UTF-8"?>
<MediaInfo xmlns="https://mediaarea.net/mediainfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://mediaarea.net/mediainfo https://mediaarea.net/mediainfo/mediainfo_2_0.xsd" version="2.0">
<creatingLibrary version="18.03" url="https://mediaarea.net/MediaInfo">MediaInfoLib</creatingLibrary>
<media ref="Krtek a buldozer-jdvwqZUEbhc.mkv">
<track type="General">
<UniqueID>101120522676894244607292274887483611459</UniqueID>
<VideoCount>1</VideoCount>
<AudioCount>1</AudioCount>
<FileExtension>mkv</FileExtension>
<Format>Matroska</Format>
<Format_Version>4</Format_Version>
<FileSize>60132643</FileSize>
<Duration>374.101</Duration>
<OverallBitRate>1285912</OverallBitRate>
<FrameRate>25.000</FrameRate>
<FrameCount>9352</FrameCount>
<IsStreamable>Yes</IsStreamable>
<File_Modified_Date>UTC 2018-10-15 07:09:29</File_Modified_Date>
<File_Modified_Date_Local>2018-10-15 09:09:29</File_Modified_Date_Local>
<Encoded_Application>Lavf57.71.100</Encoded_Application>
<Encoded_Library>Lavf57.71.100</Encoded_Library>
<extra>
<ErrorDetectionType>Per level 1</ErrorDetectionType>
</extra>
</track>
<track type="Video">
<StreamOrder>0</StreamOrder>
<ID>1</ID>
<UniqueID>1</UniqueID>
<Format>AVC</Format>
<Format_Profile>High</Format_Profile>
<Format_Level>4</Format_Level>
<Format_Settings_CABAC>Yes</Format_Settings_CABAC>
<Format_Settings_RefFrames>3</Format_Settings_RefFrames>
<CodecID>V_MPEG4/ISO/AVC</CodecID>
<Duration>374.080000000</Duration>
<Width>1920</Width>
<Height>1080</Height>
<Stored_Height>1088</Stored_Height>
<Sampled_Width>1920</Sampled_Width>
<Sampled_Height>1080</Sampled_Height>
<PixelAspectRatio>1.000</PixelAspectRatio>
<DisplayAspectRatio>1.778</DisplayAspectRatio>
<FrameRate_Mode>CFR</FrameRate_Mode>
<FrameRate_Mode_Original>VFR</FrameRate_Mode_Original>
<FrameRate>25.000</FrameRate>
<FrameCount>9352</FrameCount>
<ColorSpace>YUV</ColorSpace>
<ChromaSubsampling>4:2:0</ChromaSubsampling>
<BitDepth>8</BitDepth>
<ScanType>Progressive</ScanType>
<Delay>0.000</Delay>
<Default>Yes</Default>
<Forced>No</Forced>
<colour_range>Limited</colour_range>
<colour_description_present>Yes</colour_description_present>
<colour_primaries>BT.709</colour_primaries>
<transfer_characteristics>BT.709</transfer_characteristics>
<matrix_coefficients>BT.709</matrix_coefficients>
</track>
<track type="Audio">
<StreamOrder>1</StreamOrder>
<ID>2</ID>
<UniqueID>2</UniqueID>
<Format>Opus</Format>
<CodecID>A_OPUS</CodecID>
<Duration>374.101000000</Duration>
<Channels>2</Channels>
<ChannelPositions>Front: L R</ChannelPositions>
<SamplingRate>48000</SamplingRate>
<SamplingCount>17956848</SamplingCount>
<BitDepth>32</BitDepth>
<Compression_Mode>Lossy</Compression_Mode>
<Delay>0.000</Delay>
<Delay_Source>Container</Delay_Source>
<Language>en</Language>
<Default>Yes</Default>
<Forced>No</Forced>
</track>
</media>
</MediaInfo>
now say that I want to get all IDs:
... | xmlstarlet sel -t -v "//ID"
and nothing is printed. What? Why? Well it turned out, that if i remove all parameters from tag on second line, the same selection command will work. Now I undestand, that xmlstarlet (probably) works just fine, I'm just missing some magic flag or syntax, so that it can process xmls with defined namespaces. Can someone advice?
You need to use the namespace with -N option, and use it in the query like <namespace>:<xpath>:
... | xmlstarlet sel -N n="https://mediaarea.net/mediainfo" -t -v "//n:ID"
From the help page:
-N <name>=<value>
- predefine namespaces (name without 'xmlns:')
ex: xsql=urn:oracle-xsql
Multiple -N options are allowed.
I want to add this block after </audio_selector>
<input_clipping>
<end_timecode>00:00:05:00</end_timecode>
<order>1</order>
<order>2</order>
<start_timecode>00:00:01:00</start_timecode>
</input_clipping>
Below is my expected output:
<?xml version="1.0" encoding="UTF-8"?>
<job href="/jobs/35932" version="2.10.0.44452">
<input>
<deblock_enable>Auto</deblock_enable>
<deblock_strength>0</deblock_strength>
<no_psi>false</no_psi>
<order>1</order>
<timecode_source>zerobased</timecode_source>
<file_input>
<certificate_file nil="true"/>
<password>xxx</password>
<uri>s3_source</uri>
<username>xxx</username>
</file_input>
<name>input_1</name>
<video_selector>
<color_space>follow</color_space>
<order>1</order>
<program_id nil="true"/>
<name>input_1_video_selector_0</name>
</video_selector>
<audio_selector>
<default_selection>true</default_selection>
<infer_external_filename>false</infer_external_filename>
<order>1</order>
<program_selection>1</program_selection>
<selector_type>track</selector_type>
<track>1, 2</track>
<unwrap_smpte337>true</unwrap_smpte337>
<name>input_1_audio_selector_0</name>
</audio_selector>
<input_clipping>
<end_timecode>00:00:05:00</end_timecode>
<order>1</order>
<order>2</order>
<start_timecode>00:00:01:00</start_timecode>
</input_clipping>
</input>
<timecode_config>
<require_initial_timecode>false</require_initial_timecode>
<source>zerobased</source>
<sync_threshold nil="true"/>
</timecode_config>
<ad_trigger>scte35_splice_insert</ad_trigger>
<ad_avail_offset>0</ad_avail_offset>
<priority>100</priority>
<user_data></user_data>
<avsync_enable>true</avsync_enable>
<avsync_pad_trim_audio>true</avsync_pad_trim_audio>
<stream_assembly>
<name>stream_assembly_0</name>
<video_description>
<afd_signaling>None</afd_signaling>
<anti_alias>true</anti_alias>
<drop_frame_timecode>true</drop_frame_timecode>
<fixed_afd nil="true"/>
<force_cpu_encode>false</force_cpu_encode>
<height>1080</height>
<insert_color_metadata>false</insert_color_metadata>
<respond_to_afd>None</respond_to_afd>
<sharpness>50</sharpness>
<stretch_to_output>false</stretch_to_output>
<timecode_passthrough>false</timecode_passthrough>
<vbi_passthrough>false</vbi_passthrough>
<width>1920</width>
<h264_settings>
<adaptive_quantization>medium</adaptive_quantization>
<bitrate>14000000</bitrate>
<buf_fill_pct nil="true"/>
<buf_size nil="true"/>
<cabac>true</cabac>
<flicker_reduction>off</flicker_reduction>
<force_field_pictures>false</force_field_pictures>
<framerate_denominator nil="true"/>
<framerate_follow_source>true</framerate_follow_source>
<framerate_numerator nil="true"/>
<gop_b_reference>false</gop_b_reference>
<gop_closed_cadence>1</gop_closed_cadence>
<gop_markers>false</gop_markers>
<gop_num_b_frames>2</gop_num_b_frames>
<gop_size>50.0</gop_size>
<gop_size_units>frames</gop_size_units>
<interpolate_frc>false</interpolate_frc>
<look_ahead_rate_control>medium</look_ahead_rate_control>
<max_bitrate nil="true"/>
<max_qp nil="true"/>
<min_buf_occ nil="true"/>
<min_i_interval>0</min_i_interval>
<min_qp nil="true"/>
<num_ref_frames>1</num_ref_frames>
<par_denominator nil="true"/>
<par_follow_source>true</par_follow_source>
<par_numerator nil="true"/>
<passes>1</passes>
<qp nil="true"/>
<repeat_pps>false</repeat_pps>
<rp2027_syntax>false</rp2027_syntax>
<scd>true</scd>
<sei_timecode>false</sei_timecode>
<slices>1</slices>
<slow_pal>false</slow_pal>
<softness nil="true"/>
<svq>0</svq>
<telecine>None</telecine>
<level>4.1</level>
<profile>High</profile>
<rate_control_mode>CBR</rate_control_mode>
<gop_mode>fixed</gop_mode>
<interlace_mode>progressive</interlace_mode>
</h264_settings>
<selected_gpu nil="true"/>
<codec>h.264</codec>
</video_description>
<audio_description>
<audio_type>0</audio_type>
<follow_input_audio_type>false</follow_input_audio_type>
<follow_input_language_code>false</follow_input_language_code>
<language_code>eng</language_code>
<order>1</order>
<stream_name nil="true"/>
<timecode_passthrough>false</timecode_passthrough>
<aac_settings>
<ad_broadcaster_mix>false</ad_broadcaster_mix>
<bitrate>192000</bitrate>
<coding_mode>2_0</coding_mode>
<latm_loas>false</latm_loas>
<mpeg2>false</mpeg2>
<sample_rate>48000</sample_rate>
<profile>LC</profile>
<rate_control_mode>CBR</rate_control_mode>
</aac_settings>
<codec>aac</codec>
<audio_source_name>Audio Selector 1</audio_source_name>
</audio_description>
</stream_assembly>
<output_group>
<custom_name>file_group_4</custom_name>
<name nil="true"/>
<order>1</order>
<file_group_settings>
<rollover_interval nil="true"/>
<destination>
<password>xxx</password>
<username>xxx</username>
<uri>s3_destination</uri>
</destination>
</file_group_settings>
<type>file_group_settings</type>
<output>
<description nil="true"/>
<extension>mov</extension>
<log_edit_points>false</log_edit_points>
<name_modifier></name_modifier>
<order>1</order>
<mov_settings>
<growing_reference>false</growing_reference>
<include_clap>false</include_clap>
<include_cslg>true</include_cslg>
<omneon_padding>true</omneon_padding>
<reference>self_contained</reference>
<write_xdcam>false</write_xdcam>
</mov_settings>
<stream_assembly_name>stream_assembly_0</stream_assembly_name>
<container>mov</container>
</output>
</output_group>
</job>
Here is what I tried.
xmlstarlet edit -L \
--update "//job/input/file_input/uri" \
--value 'my_source' \
--update "//job/output_group/file_group_settings/destination/uri" \
--value 'my_destination'
--append "//job/input//audio_selector" \
--type elem --name 'input_clipping' --value ''
--append "//job/input/input_clipping" \
--type elem --name 'end_timecode' --value '0:00:05:00'
--append "//job/input/end_timecode" \
--type elem --name 'order' --value '1'
--type elem --name 'order' --value '2'
--append "//job/input//audio_selector" \
--type elem --name "start_timecode" --value "0:00:01:00" file.xml
May I know what is the proper way to shorten it and make it run?
Thank you very much.
xmlstarlet solution:
Saving into file subnode.xml(just a sample name) the tag to be appended:
<input_clipping>
<end_timecode>00:00:05:00</end_timecode>
<order>1</order>
<order>2</order>
<start_timecode>00:00:01:00</start_timecode>
</input_clipping>
The job:
xmlstarlet ed -a "//job/input/audio_selector" -t elem -n input_clipping \
-v "$(xmlstarlet sel -t -c '//input_clipping/*' subnode.xml)" file.xml \
| xmlstarlet unesc
How can I extract using xmlstarlet the local port from this xml example:
<?xml version="1.0"?>
<opmn xmlns="http://www.oracle.com/ias-instance">
<notification-server>
<port local="6101" remote="6200" request="6003"/>
<log-file path="$ORACLE_HOME\opmn\logs\ons.log" level="4" rotation-size="1500000"/>
<ssl enabled="true" wallet-file="$ORACLE_HOME\opmn\conf\ssl.wlt\default"/>
</notification-server>
</opmn>
xml sel -N ias=http://www.oracle.com/ias-instance -t -v //ias:port/#local example.xml
Or more precise
xml sel -N ias=http://www.oracle.com/ias-instance -t -v /ias:opmn/ias:notification-server/ias:port/#local example.xml
With this example XML:
<rootnode>
<element-a />
<element-b />
<element-d />
<element-e />
</rootnode>
How do I insert element <element-c/> directly after the element <element-b/> using XMLStarlet?
xml ed -i (or --insert) will put the it before the node, xml ed -a (or --append) will put it after, so you can use either one of:
xml ed -i /rootnode/element-d -t elem -n element-c -v "" file.xml
xml ed -a /rootnode/element-b -t elem -n element-c -v "" file.xml