如何更改XML的结构

发布于 2025-01-28 15:52:27 字数 2095 浏览 2 评论 0原文

来自此字符串:

label_config={
    "label1": [
        "modality1",
        "modality2",
        "modality3"],
    "choice":"single",
    "required": "true",
    "name" : "sentiment"},{
    "label2": [
        "modality1",
        "modality2"],
    "name" : "price"
 }

我创建了打印的XML:

​ 可以将黄色元素的斜线从开始到开始吗?

这是一代代码:

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无法实现所需的产品,我发现,如果我进行了上述更改,它将起作用。

同时,我正在与他们的团队联系以获取更多信息,但是如果Somoeone在这里有任何了解如何使其正常工作,请挺身而出。

From this string:

label_config={
    "label1": [
        "modality1",
        "modality2",
        "modality3"],
    "choice":"single",
    "required": "true",
    "name" : "sentiment"},{
    "label2": [
        "modality1",
        "modality2"],
    "name" : "price"
 }

I created this XML which is printed:

enter image description here

Anyone knows how thanks to this library: from lxml import etree
can move the slashes of the yellow elements from the end to the beginning?

Here is the code of the generation:

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

The generated code will be used in this site https://labelstud.io/playground/. They use some type of XML do create the code. Unfortunately, using etree it doesn't achieve the wanted product and I found out that if I made the changes described above it will work.

In the meantime, I am contacting their team to get more info but if somoeone here has any idea on how to make it work, please come forward.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南薇 2025-02-04 15:52:27

要正确封装< phoice 在其父母下的节点,< choices>,只需对您的choce> pocecexml进行以下简单的两个更改。方法。也就是说,在Choisesel element(不是root)下添加opel子元素,然后删除冗余的第二choisesel line结尾。

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>

To correctly encapsulate the <Choice> nodes under its parent, <Choices>, simply make the following very simple two changes to your choiceXML method. Namely, add opEl sub elements under the choisesEl element (not root) and remove the redundant second choisesEl line at the end.

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

Full Process

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)

Output

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>
陈独秀 2025-02-04 15:52:27

&lt; choices/&gt;&lt;选择&gt;&lt;/choices&gt; xml规格)。如果您只是将其作为关闭元素,则可能没有开放元素,结果将是无效的XML。试图读取 /解析的任何程序都会出错。

请注意,您在所有&lt;元素(也是非空的元素)上都有落后的斜线。

如果您不想要空的&lt;选择/&gt;元素,则可能需要研究如何从dict生成XML。由于您不提供 mcve 我们无法回答那部分。

The <Choices/> is short for <Choices></Choices> (XML spec). If you just make it a closing element, you probably don't have an opening one, and the result will be invalid xml. Any program trying to read / parse that will error out.

Notice that you have trailing slashes on all your <Choices> elements, also the non-empty ones.

If you don't want the empty <Choices/> elements, you may need to look into how you generate the XML from the dict. Since you don't provide a MCVE we can't answer that part.

栖竹 2025-02-04 15:52:27

这比答案更重要,但要发表评论有点太长了。看着您提供的东西,似乎问题不是您的XML形成得太好(没有这样的东西),或者游乐场具有某种怪异的XML结构。我相信您生成的XML不是他们想要的。

如果您查看第二个&lt;选择&gt;元素,它会读取

<Choices toName="text" name="price"/>

删除闭合/,因此它读取:

<Choices toName="text" name="price">

然后将使用以下&lt; lt;选择/&gt;,也许它将起作用。

This is more a comment than an answer, but it's a bit too long for a comment. Looking at what you provide, it seems like the problem is not that your xml is too well formed (there's no such thing) or that the playground has some sort of weird xml structure. I believe the xml you generated is not what they are looking for.

If you look at your 2nd <Choices> element, it reads

<Choices toName="text" name="price"/>

Try dropping the closing / so it reads:

<Choices toName="text" name="price">

It will then be closed with the following <Choices/> and maybe it will work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文