XPATH (eXistdb), как заменить литерал в содержимом HTTP-запроса - PullRequest
0 голосов
/ 29 февраля 2020

Наши пользователи вводят данные в форму браузера, включая текст, который может содержать неразрывные пробелы. Когда они сохраняют данные на сервере (через AJAX запрос к eXist-db), он отправляет следующее в содержимом полезной нагрузки HTTP POST с  :

<request type="edit_collection" id="TC0002">    
  <about>Chômei a donc rédigé un recueil d’anecdotes, 
   s’intégrant dans le genre de la «&nbsp;littérature 
   d’anecdotes&nbsp;» (setsuwa bungaku), qui remonte 
   au début du IXe siècle.</about> 
</request>

Модуль, который начинает обработку HTTP-запрос сначала назначает данные полезной нагрузки для $ content:

let $content := request:get-data()

Вышеуказанное происходит без ошибок, поскольку $content - это просто строка символов, еще не проанализированная как XML , Только когда я позже передаю $content для анализа XML, возникает ошибка, отклоняя &nbsp; с ошибкой:

exerr:ERROR cannot convert xs:string('&lt;request 
type=&quot;edit_collection&quot; date=&quot;TC0002&quot;&gt;
&lt;about&gt;Chômei a donc rédigé un recueil d’anecdotes, s’intégrant 
dans le genre de la «&nbsp;littérature d’anecdotes&nbsp;» (setsuwa 
bungaku), qui remonte au début du IXe siècle.&lt;/about&gt; 
&lt;/request&gt;') to a node set 

XML Parsing Error: undefined entity

Однако простая замена &nbsp; перед синтаксическим анализом недопустима то есть XPATH (в XQuery, реализованном в eXist?) не примет &nbsp; в этой формулировке:

let $content := replace(request:get-data(),"&nbsp;","&#160;")

Есть ли какой-то другой способ заменить &nbsp; перед парсинг как XML?

(я предпочитаю делать эту очистку на стороне сервера, а не в Javascript)

1 Ответ

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

Фрагмент, который вы показали, недопустим XML - чтобы быть правильно сформированным, он должен иметь DTD, который объявил бы сущность nbsp. Так что неясно, как вы обрабатываете это, или почему это происходит настолько далеко, насколько это возможно.

Если было DTD, то контент, видимый процессором XQuery (как доставлено парсером XML) ) будет расширением сущности (предположительно, одним символом xA0), и запросу не потребуется выполнять какую-либо работу, чтобы понять или перевести его.

Возможно, здесь происходит что-то еще: возможно, фрагмент показано, что на самом деле внутри раздела CDATA, так что он передается без изменений парсером XML?

== UPDATE ==

Вы объяснили, что фактически обрабатываете символьная строка, содержащая последовательность из шести символов &nbsp;, и вы хотите заменить ее одним символом xA0.

В абстрактных терминах выражение XPath replace('&nbsp;', '_') (где '_' - xA0) будет сделай это; вопрос заключается в том, как express это в конкретном синтаксисе, и это зависит от языка хоста. Это также область, где XQuery отличается от XPath. В частности, XQuery использует XML правила для экранирования специальных символов в строковых литералах (но не в других местах), в то время как XPath не делает экранирования и не экранирования, для этого он использует язык хоста.

В XQuery, я думаю, что правильное выражение - replace('&amp;nbsp;', '&#xa0;').

Но здесь возникает другой вопрос: почему браузер отправляет некорректно XML в своем HTTP-запросе POST? Правильно сформированный XML не содержит неопределенных ссылок на сущности, таких как &nbsp;. Вместо того, чтобы пытаться восстановить XML в получателе, разве вы не должны смотреть, почему у вас отрывается XML от отправителя?

...