Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
use QM to quickly modify the keys and values ​​in a plist file
#1
Hello everyone, I often use text editing software (EmEditor) modify the file of plist type.


I think the plist file is actually an xml file. In the help of QM, I saw that qm can manipulate xml, but I don't know how to implement it.

Here's an example, I hope someone can help me write a sample code, thanks in advance
___________________________________________________________________________________
Look for the key20 in the full text, if not found, add a key key20 under the key5, its value: string20


Look for the key7 in the full text, if found, if its property value is false, then modify it to true

Look for the key9 in the full text, if found, delete its key and value
___________________________________________________________________________________


Attached Files Image(s)
   

.zip   plist_file.zip (Size: 346 bytes / Downloads: 382)
#2
Using text editing software to find and modify, it is too much trouble. I hope that my friends who are proficient in QM programming can help me complete the above examples, so that more people can refer to and use them.  Smile
#3
this is just a basic how to   load the file into qm using IXml

Code:
Copy      Help
IXml x._create
x.FromFile("$desktop$\plist_file\file.plist")
str s
x.ToString(s) ;;compose xml string from loaded file and send to output
out s
#4
How to identify keys and values? Is it troublesome to handle with QM?   Huh

I usually use the file editing software. After opening the file, using the search function, is there a faster and faster way?
#5
create this function

Function XmlOut
Code:
Copy      Help
function IXml&xml [withAttr]

;This function displays all XML nodes and their properties.
;To test it, create new function, name it XmlOut and paste this code.

;EXAMPLE
;IXml x=CreateXml
;x.FromFile("$my qm$\test.xml")
;XmlOut x 1


lpstr st="root[]el[]a[]text[]xml[]DOC[]PI[]CD[]comm"
ARRAY(str) at=st

ARRAY(IXmlNode) a; int i
xml.Root.GetAll(withAttr!=0 a)

for(i 0 a.len)
,XMLNODE xi; a[i].Properties(&xi)
,out "%-15s %-4s F=0x%X L=%i V='%s'", xi.name, at[xi.xtype], xi.flags, xi.level, xi.value
then put this code in a  different macro or function


Code:
Copy      Help
IXml x._create
x.FromFile("$desktop$\plist_file\file.plist")
XmlOut x 1
it will show you details of the xml structure
#6
My programming level is low, understanding the code is a little difficult, how to use conditional statements, search and modify key values?

My idea is to react the key values to a dialog box. The drop-down list in the dialog box allows you to select the key and then change the value directly. Smile
#7
are you wanting to remove <key>key9</key>
or 
<string>string6</string>
or both
<key>key9</key>
and
<string>string6</string> ??????

here is what you wanted to do not sure you will understand the code though

Code:
Copy      Help
IXml x._create
x.FromFile("$desktop$\plist_file\file.plist")
int t tt
ARRAY(IXmlNode) a b; int i
x.RootElement.GetAll(0 a)
for i 0 a.len
,IXmlNode n=a[i]
,if(!StrCompare(n.Value "key20"))
,,t=1
,if(!StrCompare(n.Value "key7"))
,,n=n.Next
,,if(!StrCompare(n.Name "false"))
,,,n.Name="true"
,if(!StrCompare(n.Value "key9"))
,,x.Delete(n);; remove <key>key9</key>
,,n=a[i+1]
,,if(!StrCompare(n.Name "string"))
,,,x.Delete(n);; remove <string>string6</string>
if(t!=1)
,x.Path("plist/dict/dict").GetAll(0 b)
,for i 0 b.len
,,sel b[i].Name
,,,case "key"
,,,if(!StrCompare(b[i].Value "key5"))
,,,,IXmlNode iafter
,,,,iafter=b[i+1]
,,,,b[i].Parent.Insert(iafter "string" "string20")
,,,,b[i].Parent.Insert(iafter "key" "key20")                
x.ToString(_s)
out _s
#8
@kevin

Thank you very much, I can understand the code, some of the functions used in it, I saw it for the first time.

I run the code, found a problem, with a space after the false and true, as shown in the image below.

In addition, how to generate the .plist file after processing the code, put it in the same directory as the original file, the file name is file_fix.plist


Attached Files Image(s)
   
#9
the space shouldn't make a difference
if it does will have to wait for Gintaras to help you sort that

to save is easy 
Code:
Copy      Help
x.ToFile("$desktop$\plist_file\file.plist")
#10
Thank you very much for your help. 

Now, I am using QM to modify XML. It is very convenient. Smile

In the example above:

1. Add the key value of key20, only one group, how to add the following multiple sets of key values?

2. How to replace all the key values of key5 with the key values of the following ?     Huh


Code:
Copy      Help
            <key>key20</key>
            <array>
                <dict>
                    <key>Comment</key>
                    <string>Comment1</string>
                    <key>Disabled</key>
                    <true/>
                    <key>Find</key>
                    <data>Comment1</data>
                    <key>Replace</key>
                    <data>Comment1+</data>
                </dict>
                <dict>
                    <key>Comment</key>
                    <string>Comment2</string>
                    <key>Disabled</key>
                    <true/>
                    <key>Find</key>
                    <data>Comment2</data>
                    <key>Replace</key>
                    <data>Comment2+</data>
                </dict>
                <dict>
                    <key>Comment</key>
                    <string>Comment3</string>
                    <key>Disabled</key>
                    <true/>
                    <key>Find</key>
                    <data>Comment3</data>
                    <key>Replace</key>
                    <data>Comment3+</data>
                </dict>
            </array>
Code:
Copy      Help
            <key>key5</key>
            <array>
                <dict>
                    <key>Comment</key>
                    <string>Comment1</string>
                    <key>Disabled</key>
                    <true/>
                    <key>Find</key>
                    <data>Comment1</data>
                    <key>Replace</key>
                    <data>Comment1+</data>
                </dict>
                <dict>
                    <key>Comment</key>
                    <string>Comment2</string>
                    <key>Disabled</key>
                    <true/>
                    <key>Find</key>
                    <data>Comment2</data>
                    <key>Replace</key>
                    <data>Comment2+</data>
                </dict>
                <dict>
                    <key>Comment</key>
                    <string>Comment3</string>
                    <key>Disabled</key>
                    <true/>
                    <key>Find</key>
                    <data>Comment3</data>
                    <key>Replace</key>
                    <data>Comment3+</data>
                </dict>
            </array>
#11
need to use x.Path to find the location
 has previous example plus new 1
Function IxmlExample2 
Code:
Copy      Help
IXml x._create
x.FromFile("$desktop$\plist_file\file.plist")
int t tt
ARRAY(IXmlNode) a b c; int i
x.RootElement.GetAll(0 a)
for i 0 a.len
,IXmlNode n=a[i]
,if(!StrCompare(n.Value "key20"))
,,t=1
,if(!StrCompare(n.Value "key7"))
,,n=n.Next
,,if(!StrCompare(n.Name "false"))
,,,n.Name="true"
,if(!StrCompare(n.Value "key9"))
,,x.Delete(n);; remove <key>key9</key>
,,n=a[i+1]
,,if(!StrCompare(n.Name "string"))
,,,x.Delete(n);; remove <string>string6</string>
if(t!=1)
,x.Path("plist/dict/dict").GetAll(0 b)
,for i 0 b.len
,,sel b[i].Name
,,,case "key"
,,,if(!StrCompare(b[i].Value "key5"))
,,,,IXmlNode iafter
,,,,iafter=b[i+1]
,,,,b[i].Parent.Insert(iafter "string" "string20")
,,,,b[i].Parent.Insert(iafter "key" "key20")    
x.ToString(_s)
out _s
x.Path("plist/dict/dict/[key='key5']/array").GetAll(0 c)
for i 0 c.len
,n=c[i]
,if(!StrCompare(n.Name "string"))
,,x.Delete(n);; removes all <string>string*</string> from <key>key5</key>
n=x.Path("plist/dict/dict/[key='key5']/array");; path to key5 array
n.Add("dict" "").Add("key" "Comment").Parent.Add("string" "Comment1").Parent.Add("key" "Disabled").Parent.Add("true").Parent.Add("key" "Find").Parent.Add("data" "Comment1").Parent.Add("key" "Replace").Parent.Add("data" "Comment1+")
n.Add("dict" "").Add("key" "Comment").Parent.Add("string" "Comment2").Parent.Add("key" "Disabled").Parent.Add("true").Parent.Add("key" "Find").Parent.Add("data" "Comment2").Parent.Add("key" "Replace").Parent.Add("data" "Comment2+")
n.Add("dict" "").Add("key" "Comment").Parent.Add("string" "Comment3").Parent.Add("key" "Disabled").Parent.Add("true").Parent.Add("key" "Find").Parent.Add("data" "Comment3").Parent.Add("key" "Replace").Parent.Add("data" "Comment3+")
IXmlNode e=x.Path("plist/dict/dict/string[='string20']");; path to <string>string20</string>
e.Value=""
e.Name="array";; change <string>string20</string> to <array></array>
;adds new data to <key>key20</key> <array>*data added here</array>
e.Add("dict" "").Add("key" "Comment").Parent.Add("string" "Comment1").Parent.Add("key" "Disabled").Parent.Add("true").Parent.Add("key" "Find").Parent.Add("data" "Comment1").Parent.Add("key" "Replace").Parent.Add("data" "Comment1+")
e.Add("dict" "").Add("key" "Comment").Parent.Add("string" "Comment2").Parent.Add("key" "Disabled").Parent.Add("true").Parent.Add("key" "Find").Parent.Add("data" "Comment2").Parent.Add("key" "Replace").Parent.Add("data" "Comment2+")
e.Add("dict" "").Add("key" "Comment").Parent.Add("string" "Comment3").Parent.Add("key" "Disabled").Parent.Add("true").Parent.Add("key" "Find").Parent.Add("data" "Comment3").Parent.Add("key" "Replace").Parent.Add("data" "Comment3+")

x.ToString(_s)
out _s
x.ToFile("$desktop$\plist_file\file.plist")
#12
Is there an easier way? The code in the back part takes a lot of time   Confused

Can it be replaced as a whole?
#13
Can I replace it directly with a regular expression? Such as replacerx("s" "d")

I think that when there is too much code to be modified, it should be convenient to replace it. But how to preserve the format of the xml code? Huh


Forum Jump:


Users browsing this thread: 2 Guest(s)