如何更改 python 中 XML 的结构
How to change the structure of a an XML in python
来自这个字符串:
label_config={
"label1": [
"modality1",
"modality2",
"modality3"],
"choice":"single",
"required": "true",
"name" : "sentiment"},{
"label2": [
"modality1",
"modality2"],
"name" : "price"
}
我创建了这个 XML 打印出来:
任何人都知道如何感谢这个库:from lxml import etree
可以把黄色元素的斜线从末尾移到开头吗?
生成代码如下:
from lxml import etree
import sys
def topXML(dictAttrib = None):
root : {lxml.etree._Element}
root = etree.Element("View")
textEl = etree.SubElement(root, "Text")
if dictAttrib == None:
dictAttrib = {
"name":"text",
"value":"$text"
}
for k_,v_ in dictAttrib.items():
textEl.set(k_,v_)
return root
def choiceXML(root,locChoice):
headerEl = etree.SubElement(root, "Header")
choisesEl = etree.SubElement(root, "Choices")
for k_,v_ in locChoice.items():
if (isinstance(k_,str) & isinstance(v_,list)):
choices = v_
headerEl.set("value",k_)
if locChoice.get("toName") == None:
choisesEl.set("toName","text")
for op_ in choices:
opEl = etree.SubElement(root, "Choice")
opEl.set("value",op_)
else :
choisesEl.set(k_,v_)
choisesEl = etree.SubElement(root, "Choices")
return root
def checkConfig(locChoice):
if locChoice.get("name") == None :
sys.exit("Warning : label_config needs a parameter called 'name' assigned")
def xmlConstructor(label_config):
root = topXML()
for ch_ in label_config:
checkConfig(ch_)
root = choiceXML(root,ch_)
return root
生成的代码将用于此站点 https://labelstud.io/playground/。他们使用某种类型的 XML 来创建代码。不幸的是,使用 etree 并没有得到想要的产品,我发现如果我进行了上述更改,它就会起作用。
与此同时,我正在联系他们的团队以获取更多信息,但如果这里有人对如何让它发挥作用有任何想法,请站出来。
我乐于接受所有建议,但我正在寻找结构良好的解决方案,而不是通过附加代码片段来创建代码。
<Choices/>
是 <Choices></Choices>
(XML spec) 的缩写。如果你只是让它成为一个结束元素,你可能没有一个开放元素,结果将是无效的xml。任何试图读取/解析的程序都会出错。
请注意,您在所有 <Choices>
元素以及 non-empty 元素上都有尾部斜杠。
如果您不想要空的 <Choices/>
元素,您可能需要研究如何从字典生成 XML。由于您没有提供 MCVE 我们无法回答该部分。
这与其说是一个答案,不如说是一个评论,但对于评论来说有点太长了。查看您提供的内容,似乎问题不在于您的 xml 格式太好(没有这样的东西)或者操场有某种奇怪的 xml 结构。我相信您生成的 xml 不是他们想要的。
如果您查看第二个 <Choices>
元素,它显示为
<Choices toName="text" name="price"/>
尝试去掉结尾的 /
,使其显示为:
<Choices toName="text" name="price">
然后用下面的<Choices/>
关闭它,也许它会起作用。
要将 <Choice>
节点正确封装在其父节点 <Choices>
下,只需对 choiceXML
方法进行以下非常简单的两个更改。即,在 choisesEl
元素下添加 opEl
子元素(不是 root
),并删除末尾多余的第二行 choisesEl
。
def choiceXML(root, locChoice):
headerEl = etree.SubElement(root, "Header")
choisesEl = etree.SubElement(root, "Choices")
for k_,v_ in locChoice.items():
if (isinstance(k_,str) & isinstance(v_,list)):
choices = v_
headerEl.set("value",k_)
if locChoice.get("toName") == None:
choisesEl.set("toName","text")
for op_ in choices:
opEl = etree.SubElement(choisesEl, "Choice") # CHANGE root to choisesEl
opEl.set("value",op_)
else :
choisesEl.set(k_,v_)
#choisesEl = etree.SubElement(root, "Choices") # REMOVE THIS LINE
return root
全过程
label_config = {
"label1": [
"modality1",
"modality2",
"modality3"],
"choice":"single",
"required": "true",
"name" : "sentiment"},{
"label2": [
"modality1",
"modality2"],
"name" : "price"
}
def topXML(dictAttrib = None):
# ...NO CHANGE...
def choiceXML(root,locChoice):
# ...ABOVE CHANGE...
def checkConfig(locChoice):
# ...NO CHANGE...
def xmlConstructor(label_config):
# ...NO CHANGE...
output = xmlConstructor(label_config)
输出
print(etree.tostring(output, pretty_print=True).decode("utf-8"))
# <View>
# <Text name="text" value="$text"/>
# <Header value="label1"/>
# <Choices toName="text" choice="single" required="true" name="sentiment">
# <Choice value="modality1"/>
# <Choice value="modality2"/>
# <Choice value="modality3"/>
# </Choices>
# <Header value="label2"/>
# <Choices toName="text" name="price">
# <Choice value="modality1"/>
# <Choice value="modality2"/>
# </Choices>
# </View>
来自这个字符串:
label_config={
"label1": [
"modality1",
"modality2",
"modality3"],
"choice":"single",
"required": "true",
"name" : "sentiment"},{
"label2": [
"modality1",
"modality2"],
"name" : "price"
}
我创建了这个 XML 打印出来:
任何人都知道如何感谢这个库:from lxml import etree 可以把黄色元素的斜线从末尾移到开头吗?
生成代码如下:
from lxml import etree
import sys
def topXML(dictAttrib = None):
root : {lxml.etree._Element}
root = etree.Element("View")
textEl = etree.SubElement(root, "Text")
if dictAttrib == None:
dictAttrib = {
"name":"text",
"value":"$text"
}
for k_,v_ in dictAttrib.items():
textEl.set(k_,v_)
return root
def choiceXML(root,locChoice):
headerEl = etree.SubElement(root, "Header")
choisesEl = etree.SubElement(root, "Choices")
for k_,v_ in locChoice.items():
if (isinstance(k_,str) & isinstance(v_,list)):
choices = v_
headerEl.set("value",k_)
if locChoice.get("toName") == None:
choisesEl.set("toName","text")
for op_ in choices:
opEl = etree.SubElement(root, "Choice")
opEl.set("value",op_)
else :
choisesEl.set(k_,v_)
choisesEl = etree.SubElement(root, "Choices")
return root
def checkConfig(locChoice):
if locChoice.get("name") == None :
sys.exit("Warning : label_config needs a parameter called 'name' assigned")
def xmlConstructor(label_config):
root = topXML()
for ch_ in label_config:
checkConfig(ch_)
root = choiceXML(root,ch_)
return root
生成的代码将用于此站点 https://labelstud.io/playground/。他们使用某种类型的 XML 来创建代码。不幸的是,使用 etree 并没有得到想要的产品,我发现如果我进行了上述更改,它就会起作用。
与此同时,我正在联系他们的团队以获取更多信息,但如果这里有人对如何让它发挥作用有任何想法,请站出来。
我乐于接受所有建议,但我正在寻找结构良好的解决方案,而不是通过附加代码片段来创建代码。
<Choices/>
是 <Choices></Choices>
(XML spec) 的缩写。如果你只是让它成为一个结束元素,你可能没有一个开放元素,结果将是无效的xml。任何试图读取/解析的程序都会出错。
请注意,您在所有 <Choices>
元素以及 non-empty 元素上都有尾部斜杠。
如果您不想要空的 <Choices/>
元素,您可能需要研究如何从字典生成 XML。由于您没有提供 MCVE 我们无法回答该部分。
这与其说是一个答案,不如说是一个评论,但对于评论来说有点太长了。查看您提供的内容,似乎问题不在于您的 xml 格式太好(没有这样的东西)或者操场有某种奇怪的 xml 结构。我相信您生成的 xml 不是他们想要的。
如果您查看第二个 <Choices>
元素,它显示为
<Choices toName="text" name="price"/>
尝试去掉结尾的 /
,使其显示为:
<Choices toName="text" name="price">
然后用下面的<Choices/>
关闭它,也许它会起作用。
要将 <Choice>
节点正确封装在其父节点 <Choices>
下,只需对 choiceXML
方法进行以下非常简单的两个更改。即,在 choisesEl
元素下添加 opEl
子元素(不是 root
),并删除末尾多余的第二行 choisesEl
。
def choiceXML(root, locChoice):
headerEl = etree.SubElement(root, "Header")
choisesEl = etree.SubElement(root, "Choices")
for k_,v_ in locChoice.items():
if (isinstance(k_,str) & isinstance(v_,list)):
choices = v_
headerEl.set("value",k_)
if locChoice.get("toName") == None:
choisesEl.set("toName","text")
for op_ in choices:
opEl = etree.SubElement(choisesEl, "Choice") # CHANGE root to choisesEl
opEl.set("value",op_)
else :
choisesEl.set(k_,v_)
#choisesEl = etree.SubElement(root, "Choices") # REMOVE THIS LINE
return root
全过程
label_config = {
"label1": [
"modality1",
"modality2",
"modality3"],
"choice":"single",
"required": "true",
"name" : "sentiment"},{
"label2": [
"modality1",
"modality2"],
"name" : "price"
}
def topXML(dictAttrib = None):
# ...NO CHANGE...
def choiceXML(root,locChoice):
# ...ABOVE CHANGE...
def checkConfig(locChoice):
# ...NO CHANGE...
def xmlConstructor(label_config):
# ...NO CHANGE...
output = xmlConstructor(label_config)
输出
print(etree.tostring(output, pretty_print=True).decode("utf-8"))
# <View>
# <Text name="text" value="$text"/>
# <Header value="label1"/>
# <Choices toName="text" choice="single" required="true" name="sentiment">
# <Choice value="modality1"/>
# <Choice value="modality2"/>
# <Choice value="modality3"/>
# </Choices>
# <Header value="label2"/>
# <Choices toName="text" name="price">
# <Choice value="modality1"/>
# <Choice value="modality2"/>
# </Choices>
# </View>