Python не удалось сохранить некоторые CLOB xml в xml файл - PullRequest
0 голосов
/ 15 февраля 2020

У меня есть xml, сохраненный как CLOB в моей базе данных oracle:

<?xml version="1.0" encoding="UTF-8"?>
<DCResponse>
...
</DCResponse>

, и с этим кодом python я могу сохранять содержимое в xml файле:

sql = "select extract(xmltype.createxml(xml), '//DCResponse').getStringVal() from table t where id = 2"
for row in cursor.execute(sql):
    print(row[0])
with open("output.xml", "w") as f:
    f.write(row[0])

Вместо этого xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<PIPEDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:XML-PIPE 
PIPEDocument.xsd" ReferenceNumber="567862650" CreationDate="20200115155255" Version="1.0"  
xmlns="urn:XML-PIPE">
...
</PIPEDocument>

Я не могу извлечь содержимое с помощью python. Аргумент write () должен быть str, а не None ....., это приводит к тому, что консоль Python выполняет этот код:

sql = "select extract(xmltype.createxml(xml), '//PIPEDocument').getStringVal() from table t where id 
= 7"
for row in cursor.execute(sql):
    print(row[0])
with open("output.xml", "w") as f:
    f.write(row[0])

В моем клиенте oracle выходные данные запроса sql ниже , используется в python, имеет значение null:

select extract(xmltype.createxml(xml), '//PIPEDocument').getStringVal() from table t where id = 7;

, в то время как содержимое xml присутствует в моей БД:

select xml from table where id =7

Не уверен, в чем проблема, может быть, ключевое слово «// PIPEDocument» в запросе выбора или другой кодировке между файлами 2 XML, но не знаю, как это исправить.

Пожалуйста, помогите с наилучшими пожеланиями Джанкарло

Ответы [ 2 ]

1 голос
/ 15 февраля 2020

Проблема в том, что во втором документе XML есть пространства имен. Элемент <PIPEDocument> находится в пространстве имен xmlns="urn:XML-PIPE", а ваше выражение XPath //PIPEDocument' соответствует только элементам <PIPEDocument> в пространстве имен 'default'.

Если вы хотите использовать пространства имен с extract Вы должны добавить:

  • отображение пространства имен префикса в URI пространства имен, используя необязательный третий аргумент extract. Этот третий аргумент является строкой, отформатированной так же, как атрибуты xmlns:* в XML документах. Вы не можете отобразить пространство имен по умолчанию таким образом, поэтому xmlns="urn:XML-PIPE" здесь не будет работать. Вместо этого используйте префикс, такой как p или, возможно, pipe.

  • , добавьте префикс к выражению XPath во втором аргументе в extract.

Я внес эти изменения в ваш код, решив использовать префикс пространства имен p. Я также обернул всю строку SQL в тройные кавычки, чтобы избежать необходимости избегать кавычек внутри нее. Это дало мне следующее, которое вернуло желаемый XML вывод:

sql = """select extract(xmltype.createxml(xml), '//p:PIPEDocument', 'xmlns:p="urn:XML-PIPE"').getStringVal() from table t where id = 7"""
for row in cursor.execute(sql):
    print(row[0])
0 голосов
/ 16 февраля 2020

Для повышения производительности запроса может потребоваться получить большой объект в виде строки, см. do c.

Для общего ознакомления, если тип базы данных был XMLType, cx_ Oracle рекомендует использовать xmltype.getclobval(), чтобы избежать ограничения XML длины.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...