-1

Team,

I have below xml file which is missing a node at line 9. so I need to insert it and not anywhere else.

line to insert

<file branch-rate="0.0" complexity="0" path="src/common/test2.go" ......>

xml file i have that is missing node is below

<?xml version="1.0" ?>
<!DOCTYPE coverage
  SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-04.dtd'>
<coverage branch-rate="0.0" branches-covered="0" branches-valid="0" complexity="0" line-rate="0.5423496311641774" lines-covered="77492" lines-valid="142882" timestamp="1677260258" version="1">
                <file branch-rate="0.0" complexity="0" path="src/common/test1.go" line-rate="0.0" name="src.common.test1.go">
                        <lineToCover branch="false" covered="false" lineNumber="15"/>
                        <lineToCover branch="false" covered="false" lineNumber="16"/>
                </file>
                        <lineToCover branch="false" covered="false" lineNumber="17"/>
                        <lineToCover branch="false" covered="false" lineNumber=“18”/>
                <file branch-rate="0.0" complexity="0" path="src/common/test3.go" line-rate="0.0" name="src.common.test3.go">
                        <lineToCover branch="false" covered="false" lineNumber="19”/>
                        <lineToCover branch="false" covered="false" lineNumber=“20”/>
                </file>
</coverage>

I tried xmlStarlet with single attribute and that itself does not get inserted.

xmlstarlet ed --subnode "/coverage/file" --type elem -n file -v "" coverage-so.xml | xmlstarlet ed --insert //coverage/file --type attr -n "branch-rate"  -v "0.0" 

output

Command> xmlstarlet ed --subnode "/coverage/file" --type elem -n file -v "" coverage-so.xml | xmlstarlet ed --insert //coverage/file --type attr -n "branch-rate"  -v "0.0"
coverage-so.xml:11.40: Opening and ending tag mismatch: coverage line 4 and file
                                </file>
                                       ^
coverage-so.xml:12.5: Extra content at the end of the document
                                <file branch-rate="0.0" complexity="0" path="src/common/test3.go" line-rate=
                                ^
-:1.1: Document is empty

^

expected output Observe line 9 has new entry that needs to be inserted.

<?xml version="1.0" ?>
<!DOCTYPE coverage
  SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-04.dtd'>
<coverage branch-rate="0.0" branches-covered="0" branches-valid="0" complexity="0" line-rate="0.5423496311641774" lines-covered="77492" lines-valid="142882" timestamp="1677260258" version="1">
                <file branch-rate="0.0" complexity="0" path="src/common/test1.go" line-rate="0.0" name="src.common.test1.go">
                        <lineToCover branch="false" covered="false" lineNumber="15"/>
                        <lineToCover branch="false" covered="false" lineNumber="16"/>
                </file>
                                <file branch-rate="0.0" complexity="0" path="src/common/test2.go" line-rate="0.0" name="src.common.test2.go">
                                            <lineToCover branch="false" covered="false" lineNumber="17”/>
                        <lineToCover branch="false" covered="false" lineNumber=“18”/>
                                </file>
                <file branch-rate="0.0" complexity="0" path="src/common/test3.go" line-rate="0.0" name="src.common.test3.go">
                        <lineToCover branch="false" covered="false" lineNumber="19”/>
                        <lineToCover branch="false" covered="false" lineNumber=“20”/>
                                </file>
</coverage>
1
  • Your question is unclear; for example, in the "before" file you have <lineToCover branch="false" covered="false" lineNumber="42"/>; but it's not in the "after" file. So are you making other changes as well? Commented Feb 27, 2023 at 23:14

1 Answer 1

0

The xml files in your question still have issues and are not well-formed, but I believe you are looking for something like this. Note that this needs to be done in several steps:

xmlstarlet edit \
#append a new element to the original xml in the appropriate position:
--append '//file[1]' -t elem -n "file" \
#create a new variable name referring to the previously appended element
--var newb '$prev' \
#insert a series of attributes and attribute values to the new element
--insert '$newb' -t attr -n "branch-rate" -v "0.0" \
--insert '$newb' -t attr -n "complexity" -v "0" \
--insert '$newb' -t attr -n "path" -v "src/common/test2.go" \
--insert '$newb' -t attr -n "line-rate" -v "0.0" \
#finally move the stray lineToCover elements inside the new element:
--move '//lineToCover[@lineNumber="17"]' '//file[2]' \
--move '//lineToCover[@lineNumber="42"]' '//file[2]' \
file.xml
Sign up to request clarification or add additional context in comments.

9 Comments

Will your solution work if the node I need to insert is at 8009th line? Basically can we do it dynamic instead of being dependent on line number like insert if missing kind of logic? Because my original file is like 25k lines and missing that one node.
@AhmFM In principle - yes; but it's not about the line number as such (that's irrelevant), it's about the position of the element to be inserted inside the collection of elements. In your sample xml, you have two <file> elements and the new element was inserted after the first (position 1, in xpath (not 0)). So you need to know in advance where in that order you want to insert the new element.
Got it. Thanks but it should skip if there is one already correct and not over write? Am trying your solution now.
unfortunaltely did not work. I am still getting same error as my post 11.40: Opening and ending tag mismatch: coverage line 4 and file
your code works when i manually set in the missing node then it enters the element so that implies my xml file is valid except that it is missing that node that we are trying to insert. so seems like I will have to use SED to insert though it is not preferred?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.