微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有没有创建XML元素树的方法?

如何解决有没有创建XML元素树的方法?

我目前正在编写一些XSD和DTD来验证一些XML文件,我之所以手动编写它们是因为我对XSD生成器(例如Oxygen)有非常不好的经验。

但是,我已经有一个示例XML,我需要为此做一个示例,而这个XML确实很大,例如,我有一个具有4312个子元素的元素。

由于我对XSD生成器的体验非常糟糕,所以我想创建一种XML树,该树仅包含唯一的标记属性,因此在查看XML时不必处理重复的元素。 XML来编写XSD。

我的意思是,例如,我有这个XML(由W3提供):

<?xml version="1.0" encoding="UTF-8"?>
<breakfast_menu>
<food some_attribute="1.0">
    <name>Belgian Waffles</name>
    <price>$5.95</price>
    <description>
   Two of our famous Belgian Waffles with plenty of real maple syrup
   </description>
    <calories>650</calories>
</food>
<food>
    <name>StrawBerry Belgian Waffles</name>
    <price>$7.95</price>
    <description>
    Light Belgian waffles covered with strawberries and whipped cream
    </description>
    <calories>900</calories>
</food>
<food>
    <name>Berry-Berry Belgian Waffles</name>
    <price>$8.95</price>
    <description>
    Belgian waffles covered with assorted fresh berries and whipped cream
    </description>
    <calories>900</calories>
</food>
<food>
    <name>french Toast</name>
    <price>$4.50</price>
    <description>
    Thick slices made from our homemade sourdough bread
    </description>
    <calories>600</calories>
    <some_complex_type_element_1>
      <some_simple_type_element_1>Text.</some_simple_type_element_1>
    </some_complex_type_element_1>
</food>
<food>
    <name>Homestyle Breakfast</name>
    <price>$6.95</price>
    <description>
    Two eggs,bacon or sausage,toast,and our ever-popular hash browns
    </description>
    <calories>950</calories>
    <some_simple_type_element_2>Text.</some_simple_type_element_2>
</food>
</breakfast_menu>

如您所见,根元素下面有4种独特元素。

这些是:

  • 元素1(具有属性
  • 元素2和3,
  • 元素4(还有另一个complexType元素)
  • 元素5(还有另一个simpleType元素)。

我想实现的是这种XML的树表示形式,但只包含唯一元素,而没有文本。

因此,在我的示例中(我不在乎标记内部的信息),根目录中有4个不同的唯一元素,因此我想获取文档结构的另一个XML表示或什至是ASCII表示,例如:

<?xml version="1.0" encoding="UTF-8"?>
<breakfast_menu>
<food some_attribute="">
    <name></name>
    <price></price>
    <description></description>
    <calories></calories>
</food>
<food>
    <name></name>
    <price></price>
    <description></description>
    <calories></calories>
</food>
<food>
    <name></name>
    <price></price>
    <description></description>
    <calories></calories>
    <some_complex_type_element_1>
      <some_simple_type_element_1></some_simple_type_element_1>
    </some_complex_type_element_1>
</food>
<food>
    <name></name>
    <price></price>
    <description></description>
    <calories></calories>
    <some_simple_type_element_2></some_simple_type_element_2>
</food>
</breakfast_menu>

请注意,只有标签,没有实际值,也只有唯一标签,我也想保留属性,但是我并不在意它的值,只是它现在已经存在。

第二个选项是一些ASCII,例如:

breakfast_menu
├── food some_attribute
│   ├── name
│   ├── price
│   ├── description
│   └── calories
├── food
│   ├── name
│   ├── price
│   ├── description
│   └── calories
├── food
│   ├── name
│   ├── price
│   ├── description
│   ├── calories
│   └── some_complex_type_element_1
│       └── some_simple_type_element_1
└─ food
    ├── name
    ├── price
    ├── description
    ├── calories
    └── some_simple_type_element_2

您是否知道任何软件(无论是在线的还是桌面的)都可以生成类似的内容(理想情况下在Mac上)?

或者使用python和elementtree可能吗?

我只需要生成这样的内容,我正在寻找最简单的解决方案,如果您有更好的主意(也许对此有更好的方法),我也乐于接受任何建议,因此请让我知道。

谢谢

修改

使用Power Query,通过我的测试工作,您可以生成XML的“好”表示形式。

您可以生成如下所示的XML结构,但是,它不是最大的解决方案,也不是理想的属性

enter image description here

您可以使用类似的步骤来重现此结果:

enter image description here

但这不是最干净的解决方案,我仍在寻找想法,谢谢!

解决方法

看看这是否满足您的需求。

from simplified_scrapy import SimplifiedDoc,utils

xml = '''
<?xml version="1.0" encoding="UTF-8"?>
<breakfast_menu>
    <food some_attribute="1.0">
        <name>Belgian Waffles</name>
        <price>$5.95</price>
        <description>
    Two of our famous Belgian Waffles with plenty of real maple syrup
    </description>
        <calories>650</calories>
    </food>
    <food>
        <name>Strawberry Belgian Waffles</name>
        <price>$7.95</price>
        <description>
        Light Belgian waffles covered with strawberries and whipped cream
        </description>
        <calories>900</calories>
    </food>
    <food>
        <name>Berry-Berry Belgian Waffles</name>
        <price>$8.95</price>
        <description>
        Belgian waffles covered with assorted fresh berries and whipped cream
        </description>
        <calories>900</calories>
    </food>
    <food>
        <name>French Toast</name>
        <price>$4.50</price>
        <description>
        Thick slices made from our homemade sourdough bread
        </description>
        <calories>600</calories>
        <some_complex_type_element_1>
        <some_simple_type_element_1>Text.</some_simple_type_element_1>
        </some_complex_type_element_1>
    </food>
    <food>
        <name>Homestyle Breakfast</name>
        <price>$6.95</price>
        <description>
        Two eggs,bacon or sausage,toast,and our ever-popular hash browns
        </description>
        <calories>950</calories>
        <some_simple_type_element_2>Text.</some_simple_type_element_2>
    </food>
</breakfast_menu>
'''

def loop(node):
    para = {}
    for k in node:
        if k=='tag' or k=='html': continue
        para[k] = ''
    if para: node.setAttrs(para) # Remove attributes
    children = node.children
    if children:
        for c in children:
            loop(c)
    else:
        if node.text:
            node.setContent('') # Remove value

doc = SimplifiedDoc(xml)
# Remove values and attributes
loop(doc.breakfast_menu)

dicNode = {}
for node in doc.breakfast_menu.children:
    key = node.outerHtml
    if dicNode.get(key):
        node.remove() # Delete duplicate
    else:
        dicNode[key] = True

print(doc.html)

结果:

<?xml version="1.0" encoding="UTF-8"?>
<breakfast_menu>
    <food some_attribute="">
        <name></name>
        <price></price>
        <description></description>
        <calories></calories>
    </food>
    <food>
        <name></name>
        <price></price>
        <description></description>
        <calories></calories>
    </food>
    <food>
        <name></name>
        <price></price>
        <description></description>
        <calories></calories>
        <some_complex_type_element_1>
        <some_simple_type_element_1></some_simple_type_element_1>
        </some_complex_type_element_1>
    </food>
    <food>
        <name></name>
        <price></price>
        <description></description>
        <calories></calories>
        <some_simple_type_element_2></some_simple_type_element_2>
    </food>
</breakfast_menu>

对于大文件,请尝试以下方法。

from simplified_scrapy import SimplifiedDoc,utils
from simplified_scrapy.core.regex_helper import replaceReg

filePath = 'test.xml'
doc = SimplifiedDoc()
doc.loadFile(filePath,lineByline=True)

utils.appendFile('dest.xml','<?xml version="1.0" encoding="UTF-8"?><breakfast_menu>')
dicNode = {}
for node in doc.getIterable('food'):
    key = node.outerHtml
    key = replaceReg(key,'>[^>]*?<','><')
    key = replaceReg(key,'"[^"]*?"','""')

    if not dicNode.get(key):
        dicNode[key] = True
        utils.appendFile('dest.xml',key)


utils.appendFile('dest.xml','</breakfast_menu>')

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。