0
votes

I'm trying to modify an XML file of the form:

<plist version="1.0">
<dict>
    <key>items</key>
    <array>
        <dict>
            <key>assets</key>
            <array>
                <dict>
                    <key>kind</key>
                    <string>software-package</string>
                    <key>url</key>
                    <string>https://s3.xyz.amazonaws.com/xyz/xyz.ipa</string>
                </dict>
                <dict>
                    <key>kind</key>
                    <string>display-image</string>
                    <key>url</key>
                    <string>https://s3.xyz.amazonaws.com/xyz/xyz.57x57.png</string>
                </dict>
            </array>
        </dict>
    </array>
</dict>

I want to modify the contents of the node <string>https://s3.xyz.amazonaws.com/xyz/xyz.ipa</string>

I can find the related sibling node with the following

import Text.XML.HXT.Core

main = do
  plistString <- readFile "manifest.plist"
  let plistDoc = readString [withValidate no, withSubstDTDEntities no] plistString
  node <- runX  $ plistDoc >>> deep (hasText ( == "software-package")) 
  print node

but I don't seem to be able to select the associated sibling nodes (tried followingSiblingAxis and moveUp >>> getChildren) which would then allow me to manipulate the required node. Is it a problem to do with the difference between NavigatableTree and NTree; the node I'm shows as NTree (XText "software-package") []]

It would really help me if any answers assume a very limited exposure to arrows.

Thanks.

1
I think you need to move up twice, since with hasText, you obtain the text element, not the <string> tag. As you can see with the XText.Willem Van Onsem
@WillemVanOnsem Thanks for hint which sounds right, however I'm struggling to compose moveUp with the above. It seems withNav might need to be in the mix but I'm fighting type errors without success when I'm trying to compose the whole expression. Any more hints?Nick Ager

1 Answers

0
votes

I've solved the problem in a different way. It doesn't feel as robust (matching a substring for xyz.ipa), but it unblocked me while I await inspiration:

import Text.XML.HXT.Core
import Data.Char (toUpper)

uppercase = map toUpper

main = do
  plistString <- readFile "manifest.plist"
  let plistDoc = readString [withValidate no, withSubstDTDEntities no] plistString
  node <- runX . xshow $ plistDoc >>> processTopDown (ifA (hasText ( isInfixOf "xyz.ipa")) (changeText uppercase) (this))
  print node