Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python向Plist中的deep节点添加数据_Python_Xml_Plist - Fatal编程技术网

使用Python向Plist中的deep节点添加数据

使用Python向Plist中的deep节点添加数据,python,xml,plist,Python,Xml,Plist,我有一个plist,我最初从中提取信息,然后需要向其中写入信息。使用xml.etree.ElementTree,我可以访问“WUT”,但如果我尝试用数字“1”覆盖它,或在它后面添加另一行“2”,请使用以下命令: ET.SubElement(plist[0][15][1][1][1][1][1][1][1], '1') 或与 plist[0][15][1][1][1][1][1][1][1].append('1') 我将得到一个索引越界错误,因为显然节点1还不存在 我需要添加到特定的节点(在大

我有一个plist,我最初从中提取信息,然后需要向其中写入信息。使用xml.etree.ElementTree,我可以访问“WUT”,但如果我尝试用数字“1”覆盖它,或在它后面添加另一行“2”,请使用以下命令:

ET.SubElement(plist[0][15][1][1][1][1][1][1][1], '1')
或与

plist[0][15][1][1][1][1][1][1][1].append('1')
我将得到一个索引越界错误,因为显然节点1还不存在

我需要添加到特定的节点(在大多数情况下创建该节点)。在WUT下面,我想添加大约200个随机信息的字符串儿童(现在假设1-200个)。如何使用plistlib或xml.etree.ElementTree实现这一点

<key>Title</key>
<dict>
  <key>Set</key>
  <dict>
    <key>Notes</key>
    <dict>
      <key>Tester</key>
      <array>
        <dict>
          <key>13</key>
          <dict>
            <key>Param</key>
            <array>
              <string>WUT</string>
            </array>
          </dict>
        </dict>
        <dict>
          <key>82</key>
          <dict>
            <key>Param</key>
            <array>
              <string>WUT</string>
            </array>
          </dict>
        </dict>
        <dict>
          <key>64</key>
          <dict>
            <key>Param</key>
            <array>
              <string>WUT</string>
            </array>
          </dict>
        </dict>
如果我想把它写下来,我会做类似的事情:

for plist_title in tree.xpath('//dict[key="Writing"][1]')
    for plist_tester in plist_title.xpath('//dict[key="13"][1]')
        plist_tester.insert(1,myData)
或不同的测试仪级别:

for plist_title in tree.xpath('//dict[key="Notes"][1]')
    for plist_tester in plist_title.xpath('//dict[key="82"][1]')
        plist_tester.insert(1,myData)
遗憾的是,它们不起作用:(

使用一些xpath魔法:

from lxml import etree

from lxml.builder import E

plist = """
<root>
  <key>Title</key>
  <dict>
    <key>Set</key>
    <dict>
      <key>Notes</key>
      <dict>
        <key>Tester</key>
        <array>
          <dict>
            <key>13</key>
            <dict>
              <key>Param</key>
              <array>
                <string>WUT</string>
              </array>
            </dict>
          </dict>
        </array>
      </dict>
    </dict>
  </dict>
</root>"""
创建候选元素数组:

array = E('array')

for num in range(10):
    array.append(E.string(str(num)))
下面是它的外观:

print(etree.tostring(array, pretty_print=True))
<array>
  <string>0</string>
  <string>1</string>
  <string>2</string>
  <string>3</string>
  <string>4</string>
  <string>5</string>
  <string>6</string>
  <string>7</string>
  <string>8</string>
  <string>9</string>
</array>
以下是最终版本在损坏后的外观:

print(etree.tostring(xml_data, pretty_print=True))
<root>
  <key>Title</key>
  <dict>
    <key>Set</key>
    <dict>
      <key>Notes</key>
      <dict>
        <key>Tester</key>
        <array>
          <dict>
            <key>13</key>
            <dict>
              <key>Param</key>
              <array><string>0</string><string>1</string><string>2</string><string>3</string><string>4</string><string>5</string><string>6</string><string>7</string><string>8</string><string>9</string></array></dict>
          </dict>
        </array>
      </dict>
    </dict>
  </dict>
</root>
但是,如果在第二个“13”键之后,则可以执行以下操作:

In [35]: [x.text for x in xml_data.xpath('//dict[//key[text()="13"]][2]//string')]
Out[35]: ['WUT2']

您想用字符串标记数组替换第一个
WUT
?基本上是的,但在某些情况下需要添加节点,因为WUT不存在。好的,那么您想始终将字符串数组添加到第一个
参数中
?很抱歉花了这么长时间才回复您,感谢您为得到答案付出的所有努力。一您可以帮助解决的其他问题。如果键“Notes”可以在同一plist中变为“Writing”,有没有办法使用xpath搜索“Writing”和“13”键?如果Notes和Writing都有13,我无法确定我是否找到了它。我尝试了2x for循环,但最后总是得到第二个“13”.Closer,但考虑到我给出的第一个xml,还有节点82和64,我可能不知道顺序。那么,有没有一种方法可以使用您在第一部分中提供的搜索“Writing”和搜索“13”来索引和选择正确的节点?为我尝试的for循环添加了注释,以便使其更清晰。@Dippy try
'//dict[key/text()=“Writing”]/dict[//key[text()=“13”]]“
再次感谢您的帮助。几乎完成了所有工作,只需了解这些字符串如何转换为搜索词。我在lxml的文档中没有找到太多内容。您从何处了解这些内容?@Dippy这不是lxml独有的,这是一个相当广为人知的xml解析标准。
print(etree.tostring(array, pretty_print=True))
<array>
  <string>0</string>
  <string>1</string>
  <string>2</string>
  <string>3</string>
  <string>4</string>
  <string>5</string>
  <string>6</string>
  <string>7</string>
  <string>8</string>
  <string>9</string>
</array>
for first_array_contains_wut in xml_data.xpath('//array[string="WUT"][1]'):
    parent_tag = first_array_contains_wut.getparent()
    parent_tag.remove(first_array_contains_wut)
    parent_tag.append(array)
print(etree.tostring(xml_data, pretty_print=True))
<root>
  <key>Title</key>
  <dict>
    <key>Set</key>
    <dict>
      <key>Notes</key>
      <dict>
        <key>Tester</key>
        <array>
          <dict>
            <key>13</key>
            <dict>
              <key>Param</key>
              <array><string>0</string><string>1</string><string>2</string><string>3</string><string>4</string><string>5</string><string>6</string><string>7</string><string>8</string><string>9</string></array></dict>
          </dict>
        </array>
      </dict>
    </dict>
  </dict>
</root>
<root>
  <key>Title</key>
  <dict>
    <key>Set</key>
    <dict>
      <key>Notes</key>
      <dict>
        <key>Tester</key>
        <array>
          <dict>
            <key>13</key>
            <dict>
              <key>Param</key>
              <array>
                <string>WUT</string>
              </array>
            </dict>
          </dict>
        </array>
      </dict>
      <dict>
        <key>Writing</key>
        <dict>
          <key>Tester</key>
          <array>
            <dict>
              <key>13</key>
              <dict>
                <key>Param</key>
                <array>
                  <string>WUT2</string>
                </array>
              </dict>
            </dict>
          </array>
        </dict>
      </dict>
    </dict>
  </dict>
</root>
In [26]: [x.text for x in xml_data.xpath('//dict[key/text()="Writing"]//string')]
Out[26]: ['WUT2']
In [35]: [x.text for x in xml_data.xpath('//dict[//key[text()="13"]][2]//string')]
Out[35]: ['WUT2']