XSLT: анализ текстового документа с несколькими операторами «xml»

(хотя он начинается с документа, в котором есть несколько операторов <?xml ..>, на вопрос не отвечает простое заявление о том, что это «неправильный xml». Пожалуйста, читайте дальше!)

Все еще работаю над тем же проектом, описанным в моем предыдущем вопросе XSLT: выберите шаблон, dt_assoc переменной длины внутри elem, создайте преобразование для формата записей DNS, Благодаря хорошему совету @Tim C, я перехожу к следующему этапу. Это связано с синтаксическим анализом текстового файла, состоящего из серии "документов" xml... то есть файл структурирован следующим образом:

<?xml version='1.0' encoding='UTF-8'?>
<ns2:domain xmlns:ns3="http://www.w3.org/2005/Atom" xmlns:ns2="http://docs.rackspacecloud.com/dns/api/v1.0" xmlns="http://docs.rackspacecloud.com/dns/api/management/v1.0" id="1204245" accountId="414660" name="addressing.com" ttl="300" emailAddress="[email protected]" updated="2012-10-10T21:33:36Z" created="2009-07-25T15:05:39Z">
    <ns2:nameservers>
        <ns2:nameserver name="dns1.stabletransit.com" />
        <ns2:nameserver name="dns2.stabletransit.com" />
    </ns2:nameservers>
    <ns2:recordsList totalEntries="5">
        <ns2:record id="A-2542579" type="A" name="addressing.com" data="198.101.155.141" ttl="300" updated="2012-10-10T21:33:35Z" created="2010-02-17T05:02:16Z" />
        <ns2:record id="NS-3093587" type="NS" name="addressing.com" data="dns1.stabletransit.com" ttl="300" updated="2012-10-10T21:33:35Z" created="2010-02-17T05:03:16Z" />
        <ns2:record id="NS-3093589" type="NS" name="addressing.com" data="dns2.stabletransit.com" ttl="300" updated="2012-10-10T21:33:36Z" created="2010-02-17T05:03:16Z" />
        <ns2:record id="CNAME-6051671" type="CNAME" name="vh1.addressing.com" data="vh1.eiotx.net" ttl="300" updated="2012-10-10T21:33:36Z" created="2010-02-17T05:05:09Z" />
        <ns2:record id="CNAME-6051873" type="CNAME" name="www.addressing.com" data="virtual.eiotx.net" ttl="300" updated="2012-10-10T21:33:36Z" created="2010-02-17T05:05:09Z" />
    </ns2:recordsList>
</ns2:domain>
<?xml version='1.0' encoding='UTF-8'?>
<ns2:domain xmlns:ns3="http://www.w3.org/2005/Atom" xmlns:ns2="http://docs.rackspacecloud.com/dns/api/v1.0" xmlns="http://docs.rackspacecloud.com/dns/api/management/v1.0" id="1204245" accountId="414660" name="addressing.com" ttl="300" emailAddress="[email protected]" updated="2012-10-10T21:33:36Z" created="2009-07-25T15:05:39Z">
    <ns2:nameservers>
        <ns2:nameserver name="dns1.stabletransit.com" />
        <ns2:nameserver name="dns2.stabletransit.com" />
    </ns2:nameservers>
    <ns2:recordsList totalEntries="5">
        <ns2:record id="A-2542579" type="A" name="addressing.com" data="198.101.155.141" ttl="300" updated="2012-10-10T21:33:35Z" created="2010-02-17T05:02:16Z" />
        <ns2:record id="NS-3093587" type="NS" name="addressing.com" data="dns1.stabletransit.com" ttl="300" updated="2012-10-10T21:33:35Z" created="2010-02-17T05:03:16Z" />
        <ns2:record id="NS-3093589" type="NS" name="addressing.com" data="dns2.stabletransit.com" ttl="300" updated="2012-10-10T21:33:36Z" created="2010-02-17T05:03:16Z" />
        <ns2:record id="CNAME-6051671" type="CNAME" name="vh1.addressing.com" data="vh1.eiotx.net" ttl="300" updated="2012-10-10T21:33:36Z" created="2010-02-17T05:05:09Z" />
        <ns2:record id="CNAME-6051873" type="CNAME" name="www.addressing.com" data="virtual.eiotx.net" ttl="300" updated="2012-10-10T21:33:36Z" created="2010-02-17T05:05:09Z" />
    </ns2:recordsList>
</ns2:domain>

... так далее ...

и я пытаюсь найти лучший способ управления обработкой этих отдельных фрагментов, которые теперь должны быть индивидуально переданы моему XSLT-преобразованию, а затем переданы через API POST на удаленный сервер для обработки (в новые записи зоны DNS). .

Я немного застрял, поэкспериментировав с ElementTree, думая, что, возможно, если бы я добавил новый «корень» ко всему этому, я мог бы сделать из него одно дерево и обработать каждый из элементов ns2:domain.

поэтому я попытался изменить исходный код примерно так, удалив все, кроме исходного оператора <?xml..>:

<?xml version='1.0' encoding='UTF-8'?>
<rackspace>
    <ns2:domain xmlns:ns3="http://www.w3.org/2005/Atom" ... >
    ...
    </ns2:domain>
    <ns2:domain xmlns:ns3="http://www.w3.org/2005/Atom" ... >
    ...
    </ns2:domain>
    <ns2:domain xmlns:ns3="http://www.w3.org/2005/Atom" ... >
    ...
    </ns2:domain>
</rackspace>

Тем не менее, я совершенно не знаком с ElementTree и, похоже, не могу получить какой-либо дескриптор поддеревьев «ns2:domain», которые я хотел бы целиком преобразовать в переменную, чтобы передать преобразование xslt.

#!/usr/bin/python2.7

import fileinput
import string
import re
import hashlib

from xml.etree import ElementTree as ET
from xml.etree.ElementTree import Element, SubElement, tostring

ns= {'ns2':'http://docs.rackspacecloud.com/dns/api/v1.0'}

my_outfile='/Users/peterf/Google Drive/2015 Projects-Strategy/Domain Admin/RackspaceDomains.out.txt'
my_infile='//Users/peterf/Google Drive/2015 Projects-Strategy/Domain Admin/XSL_Rackspace_to_OpenSRS/saxon.test.xml'

'''FILE=open(my_infile,"r")
OUTFILE=open(my_outfile,"w")'''

print ("**** Start Reading from Input File ****")

with open(my_infile, 'rt') as f:

     tree = ET.parse(f)

root=tree.getroot()
# ET.dump(root)

domain=SubElement(root,"ns2:domain",ns)
#ET.dump(domain)
recordsList=SubElement(root,"ns2:recordsList",ns)

#parent_map = dict((c, p) for p in tree.getiterator() for c in p)
#print parent_map

for node in recordsList:
     for node in node:
          print node.tag, node.text
          for node in node:
               print node.tag, node.text

Я не сомневаюсь, что есть простые и понятные шаги, чтобы сделать это на месте, но я просто не знаю грамматики!

Итак, псевдокод, возможно, что-то вроде этого

open my_rackspace_file.xml as rackfile
print "Start"
for each ns2:domain in rackfile:
   print "Processing ", ns2:domain/@name
   my_domain=getsubtree(ns2:domain)
   my_new_xml=`java saxon9he.jar net.sf.saxon.Transform -it < $my_domain` #Don't really know how this will work at the moment
   API_POST (my_new_xml)

print "Done"

Большое спасибо за мысли и предложения по этому поводу! Это здорово погрузиться в глубокий конец и знать, что в конце концов все это обретет смысл!

PF

Кстати, я использую Saxon XSLT 2.0, потому что мне нужны функции регулярных выражений...


person pfraterdeus    schedule 17.03.2017    source источник
comment
Вы не можете использовать синтаксический анализатор XML для решения этой проблемы, потому что ваш текст не является XML. Вы должны сначала удалить лишнее объявление XML, предпочтительно устранив проблему в источнике или вручную или программно исправив ее на уровне text, прежде чем вы сможете использовать любое соответствующее Инструменты или библиотеки на основе XML.   -  person kjhughes    schedule 17.03.2017
comment
Также обратите внимание, что помимо нескольких XML-объявлений ваши текстовые объекты также имеют несколько корневых элементов. Опять же, эта проблема корректности должна быть решена путем (предпочтительнее) исправления источника или, при необходимости, исправления на уровне текста, а не уровня XML.   -  person kjhughes    schedule 17.03.2017
comment
Спасибо за ваш вклад @kjhughes ... Я не думаю, что это так просто, как у вас. Я уже показываю, что я   -  person pfraterdeus    schedule 17.03.2017
comment
@kjhughes извините, вы имеете в виду несколько корневых элементов, поскольку DTD говорит, что ns2:domain является корневым элементом, и поэтому, даже если я вручную добавлю охватывающий элемент, то есть <rackspace>, он не будет анализироваться как правильно сформированный? Извините, это все довольно ново для меня! Спасибо   -  person pfraterdeus    schedule 17.03.2017
comment
XML-документ может иметь только один корневой элемент, да.   -  person kjhughes    schedule 17.03.2017