【问题标题】:Commenting and uncommenting XML via Python通过 Python 注释和取消注释 XML
【发布时间】:2012-01-06 20:25:25
【问题描述】:

我想知道一种使用 Python 对 XML 中的元素进行注释和取消注释的方法。

<target depends="create-build-dir" name="build-Folio">
   <property name="project.name" value="Folio"/>
   <ant antfile="build.xml" dir="Folio/FolioUI" inheritall="false" target="package"/>
   <ant antfile="build.xml" dir="Folio/Folio" inheritall="false" target="package"/>
</target>

我怎样才能让它看起来像这样:

<target depends="create-build-dir" name="build-Folio">
   <property name="project.name" value="Folio"/>
   <ant antfile="build.xml" dir="Folio/FolioUI" inheritall="false" target="deploy"/>
   <!-- <ant antfile="build.xml" dir="Folio/Folio" inheritall="false" target="deploy"/> -->
</target>

然后根据需要再次移除 cmets... 或

我正在使用来自 xml.dom 的 minidom。我需要使用不同的 XML 解析器吗?宁愿避免使用正则表达式...那将是一场噩梦。

【问题讨论】:

  • 如何指定要评论的内容(行号,x+y 位置)?
  • 如果可能的话,希望通过属性

标签: python xml ant xml-parsing minidom


【解决方案1】:

下面的脚本使用xml.dom.minidom 并包含注释和取消注释节点的函数:

from xml.dom import minidom

xml = """\
<target depends="create-build-dir" name="build-Folio">
   <property name="project.name" value="Folio"/>
   <ant antfile="build.xml" dir="Folio/FolioUI" inheritall="false" target="package"/>
   <ant antfile="build.xml" dir="Folio/Folio" inheritall="false" target="package"/>
</target>
"""

def comment_node(node):
    comment = node.ownerDocument.createComment(node.toxml())
    node.parentNode.replaceChild(comment, node)
    return comment

def uncomment_node(comment):
    node = minidom.parseString(comment.data).firstChild
    comment.parentNode.replaceChild(node, comment)
    return node

doc = minidom.parseString(xml).documentElement

comment_node(doc.getElementsByTagName('ant')[-1])

xml = doc.toxml()

print 'comment_node():\n'
print xml
print

doc = minidom.parseString(xml).documentElement

comment = doc.lastChild.previousSibling

print 're-parsed comment:\n'
print comment.toxml()
print

uncomment_node(comment)

print 'uncomment_node():\n'
print doc.toxml()
print

输出:

comment_node():

<target depends="create-build-dir" name="build-Folio">
   <property name="project.name" value="Folio"/>
   <ant antfile="build.xml" dir="Folio/FolioUI" inheritall="false" target="package"/>
   <!--<ant antfile="build.xml" dir="Folio/Folio" inheritall="false" target="package"/>-->
</target>

re-parsed comment:

<!--<ant antfile="build.xml" dir="Folio/Folio" inheritall="false" target="package"/>-->

uncomment_node():

<target depends="create-build-dir" name="build-Folio">
   <property name="project.name" value="Folio"/>
   <ant antfile="build.xml" dir="Folio/FolioUI" inheritall="false" target="package"/>
   <ant antfile="build.xml" dir="Folio/Folio" inheritall="false" target="package"/>
</target>

【讨论】:

  • 这是否适用于现有的 cmets?假设我们将其序列化到一个文件中。回来打开文件解析它然后删除评论......这个例子是否有效,它似乎仍然需要树仍然存在......
  • @MichaelBallent。是的,如果重新解析 xml,它会起作用。我更新了我的示例脚本和输出以澄清这一点。
  • 接受这个答案,因为它让我可以继续使用 minidom。非常感谢。
  • 如果我的评论是&lt;!--ant antfile="build.xml" dir="Folio/Folio" inheritall="false" target="package"&gt;&lt;/ant--&gt; 而不是&lt;!--&lt;ant antfile="build.xml" dir="Folio/Folio" inheritall="false" target="package"/&gt;--&gt;怎么办
  • @Ridhuvarshan。这是没有意义的。如果您取消注释,它将导致无效的 xml。这个问题是关于注释和取消注释 xml 标记/节点,而不是任意字符串。
【解决方案2】:
a='''<target depends="create-build-dir" name="build-Folio">
   <property name="project.name" value="Folio"/>
      <ant antfile="build.xml" dir="Folio/FolioUI" inheritall="false" target="package"/>
         <ant antfile="build.xml" dir="Folio/Folio" inheritall="false" target="package"/>
         </target>
         '''
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Comment, tostring

root = ET.fromstring(a)
element = root.getchildren()[2]
comment_element = Comment(tostring(element))
root.insert(2, comment_element)
root.remove(element)
print tostring(root)

【讨论】:

    【解决方案3】:

    使用 ElementTree:

    from xml.etree import ElementTree as etree
    
    import sys
    
    xml = """
    <target depends="create-build-dir" name="build-Folio">
       <property name="project.name" value="Folio"/>
       <ant antfile="build.xml" dir="Folio/FolioUI" inheritall="false" target="package"/>
       <ant antfile="build.xml" dir="Folio/Folio" inheritall="false" target="package"/>
    </target>
    """
    
    doc = etree.fromstring(xml)
    
    antfiles = doc.getiterator("ant")
    antfiles[1].tag = "!--"          # Comment the second antfile
    
    print etree.tostring(doc)
    
    # >>>
    # <target depends="create-build-dir" name="build-Folio">
    #    <property name="project.name" value="Folio" />
    #    <ant antfile="build.xml" dir="Folio/FolioUI" inheritall="false" target="package" />
    #    <!-- antfile="build.xml" dir="Folio/Folio" inheritall="false" target="package" />
    # </target>
    
    ###
    

    【讨论】:

    • @mzjn:你是对的,那么我会像用户一样使用 et.Comment... 在另一个答案中做到了。
    猜你喜欢
    • 1970-01-01
    • 2015-09-19
    • 2012-12-08
    • 2020-09-27
    • 2013-03-11
    • 2017-12-24
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    相关资源
    最近更新 更多