Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.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
如何基于子元素中的文本删除XML文件中的父节点?使用Python 3.6_Python_Xml_Lxml - Fatal编程技术网

如何基于子元素中的文本删除XML文件中的父节点?使用Python 3.6

如何基于子元素中的文本删除XML文件中的父节点?使用Python 3.6,python,xml,lxml,Python,Xml,Lxml,现在我正试图在Python3.6中使用lxml。我想删除包含对冲的“程序”,如果没有一个程序包含“keep”,则完全删除“Request”。 xml的结构如下所示: <Requests> <Request> <ProgramSelection> <Program> <![CDATA[hedge]]> </Program> <Program> &

现在我正试图在Python3.6中使用lxml。我想删除包含对冲的“程序”,如果没有一个程序包含“keep”,则完全删除“Request”。 xml的结构如下所示:

<Requests>
   <Request>
        <ProgramSelection>
            <Program> <![CDATA[hedge]]> </Program>
            <Program> <![CDATA[keep]] </Program>
        </ProgramSelection>
    </Request>
</Requests>

你很接近。以下两个XPath选择与删除条件匹配的元素

import lxml.etree

file_name = r'test.xml'
parser = lxml.etree.XMLParser(strip_cdata=False)
tree = lxml.etree.parse(file_name, parser)
root = tree.getroot()

# remove <Request> lacking a <Program>keep</Program>
for request in tree.xpath(
        "Request[not(ProgramSelection/Program[contains(text(),keep)])]"):
    request.getparent().remove(request)

# remove <Program>hedge</Program>
for program in tree.xpath(
        "Request/ProgramSelection/Program[contains(text(), hedge)]"):
    program.getparent().remove(program)

print(lxml.etree.tostring(tree, pretty_print=True).decode())
导入lxml.etree
文件名=r'test.xml'
parser=lxml.etree.XMLParser(strip\u cdata=False)
tree=lxml.etree.parse(文件名,解析器)
root=tree.getroot()
#脱手
对于tree.xpath中的请求(
“请求[非(程序选择/程序[包含(文本(),保留)])]”:
request.getparent().remove(请求)
#清除树篱
对于tree.xpath中的程序(
“请求/程序选择/程序[包含(文本(),对冲)]”:
program.getparent().remove(程序)
打印(lxml.etree.tostring(tree,pretty\u print=True).decode())
您可以将它们组合成可读性稍差的“或”

导入lxml.etree
文件名=r'test.xml'
parser=lxml.etree.XMLParser(strip\u cdata=False)
tree=lxml.etree.parse(文件名,解析器)
root=tree.getroot()
#脱手
#清除树篱
对于tree.xpath(“请求[
非(程序选择/程序[包含(text(),keep)])”
"|"        
“请求/程序选择/程序[包含(文本(),对冲)]”:
elem.getparent().remove(elem)
打印(lxml.etree.tostring(tree,pretty\u print=True).decode())

<代码> > p>由于使用 LXML模块,请考虑设计用于转换XML文件的专用语言。使用这种方法,对于
循环不需要
,如果需要逻辑,则不需要
。另外,XSLT是可移植的,因此可以在Python之外运行它

下面的脚本运行以按原样复制文档,然后在所需逻辑上运行两个空模板以删除其内容

XSLT(另存为.xsl文件)

输出

<?xml version="1.0"?>
<Requests>
  <Request>
    <ProgramSelection>
      <Program>keep</Program>
    </ProgramSelection>
  </Request>
</Requests>

保持

谢谢!但这似乎不起作用。关键字是否需要在单引号中?如“hedge”或“hedge fund”,如果有多个单词?并且程序选择有一些对等元素,但层次结构是正确的。不确定这是否重要,我对xml不是很在行。非常感谢。好极了很高兴XSLT没有吓跑您(就像许多Python操作一样)。如果这个解决方案有用,不要忘记StackOverflow的说法!
import lxml.etree

file_name = r'test.xml'
parser = lxml.etree.XMLParser(strip_cdata=False)
tree = lxml.etree.parse(file_name, parser)
root = tree.getroot()

# remove <Request> lacking a <Program>keep</Program>
# remove <Program>hedge</Program>
for elem in tree.xpath("Request[
        not(ProgramSelection/Program[contains(text(),keep)])]"
        "|"        
        "Request/ProgramSelection/Program[contains(text(), hedge)]"):
    elem.getparent().remove(elem)

print(lxml.etree.tostring(tree, pretty_print=True).decode())
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="text()">
      <xsl:value-of select='normalize-space()'/>
  </xsl:template>

  <xsl:template match="Program[contains(text(),'hedge')]"/>
  <xsl:template match="Request[not(contains(., 'keep'))]"/>

</xsl:stylesheet>
import lxml.etree as et

doc = et.parse('Input.xml')
xsl = et.parse('XSLT_Script.xsl')

transform = et.XSLT(xsl)    
result = transform(doc)

# OUTPUT TO SCREEN
print(result)

# OUTPUT TO FILE
with open('Output.xml', 'wb') as f:
    f.write(result)
<?xml version="1.0"?>
<Requests>
  <Request>
    <ProgramSelection>
      <Program>keep</Program>
    </ProgramSelection>
  </Request>
</Requests>