Как я могу исправить некрасивый вывод XQuery? - PullRequest
2 голосов
/ 01 мая 2011

Вот мой XML-документ:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="student.xsl"?>
<Students xmlns="www.example.com"     
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="www.example.com student.xsd">
<Student>
    <SSN>622-12-5748</SSN>
    <Name>
        <First-Name>Alexander</First-Name>
        <Last-Name>Mart</Last-Name>
    </Name>
    <Age>26</Age>
    <Institution>UCSF</Institution>
    <Email>Alexander@yahoo.com</Email>
</Student>
</Students>

У меня есть этот XQuery:

xquery version "1.0";

declare namespace xsd = "http://www.w3.org/2001/XMLSchema";
declare namespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
declare default element namespace "http://www.example.com";

for $s in doc("student.xml")/Students/Student
let $firstName := $s/First-Name
let $lastName := $s/Last-Name
let $email := $s/Email
order by $lastName ascending
return 
<row>
    <first-name> { $firstName } </first-name>
    <last-name> { $lastName } </last-name>
    <email> { $email } </email>     
</row>

Вывод, который я получаю:

<row xmlns="http://www.example.com">
    <first-name>
        <First-Name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   >Alexander</First-Name>
    </first-name>
    <last-name>
        <Last-Name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  >Mart</Last-Name>
    </last-name>
    <email>
        <Email xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              >Alexander@yahoo.com</Email>
    </email>
</row>

Все примеры, которые я вижу, выводят что-то вроде этого:

<row>
    <first-name>Alexander</first-name>
    <last-name>Mart</last-name>
    <email>Alexander@yahoo.com</email>
</row>

Как мне красиво отформатировать вывод?

Кроме того, почему я получаю это

<First-Name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

тег в моих результатах, а не просто <first-name>? Есть ли способ избавиться от этого? Я добавил declare default element namespace "http://www.example.com"; в верхней части, потому что я не мог заставить свой XQuery работать без него. Но было бы здорово, если бы это не отображалось в моих результатах.

Ответы [ 3 ]

3 голосов
/ 02 мая 2011

Используйте :

declare namespace  x = "http://www.example.com";  

for $s in /x:Students/x:Student
  let $firstName := $s/x:First-Name/text()
    let $lastName := $s/x:Last-Name/text() 
      let $email := $s/x:Email/text() 
  order by $lastName ascending 
     return  
      <row>     
        <first-name> { $firstName } </first-name>     
        <last-name> { $lastName } </last-name>     
        <email> { $email } </email>      
      </row> 

, когда это применяется к следующему документу XML (документ XML не был предоставлен вами !!!):

<Students  xmlns="http://www.example.com">
  <Student>
    <First-Name>A</First-Name>
    <Last-Name>Z</Last-Name>
    <Email>A.Z@T.com</Email>
  </Student>
</Students>

желаемый результат получен :

<row>
   <first-name>A</first-name>
   <last-name>Z</last-name>
   <email>A.Z@T.com</email>
</row>

Пояснение : буквенные элементы результата (row и т. Д.) Находятся впространство имен элемента по умолчанию.Решение не состоит в том, чтобы использовать декларацию пространства имен элемента по умолчанию.

0 голосов
/ 03 мая 2011

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

declare namespace xsd = "http://www.w3.org/2001/XMLSchema";
declare namespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
declare namespace x = "www.example.com";
declare default element namespace "http://www.example.com";
for $s in /x:Students/x:Student
let $firstName := $s/x:Name/x:First-Name
let $lastName := $s/x:Name/x:Last-Name
let $email := $s/x:Email
order by $lastName ascending
return
<row>
     <first-name> { $firstName } </first-name>
     <last-name> { $lastName } </last-name>
     <email> { $email } </email>
</row>

Это действительно вывод:

<row xmlns="http://www.example.com">
    <first-name>
        <First-Name xmlns="www.example.com"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   >Alexander</First-Name>
    </first-name>
    <last-name>
        <Last-Name xmlns="www.example.com" 
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  >Mart</Last-Name>
    </last-name>
    <email>
        <Email xmlns="www.example.com"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              >Alexander@yahoo.com</Email>
    </email>
</row>

ПОЧЕМУ? : поскольку ваш конструктор последовательности { $firstName } выводит узел, на который ссылается $firstName, а не его строковое значение. Это должно быть:

declare namespace x = "www.example.com";
declare default element namespace "http://www.example.com";
for $s in /x:Students/x:Student
let $firstName := $s/x:Name/x:First-Name
let $lastName := $s/x:Name/x:Last-Name
let $email := $s/x:Email
order by $lastName ascending
return
<row>
     <first-name> { $firstName/string() } </first-name>
     <last-name> { string($lastName) } </last-name>
     <email> { normalize-space($email) } </email>
</row>

Выход:

<row xmlns="http://www.example.com">
    <first-name>Alexander</first-name>
    <last-name>Mart</last-name>
    <email>Alexander@yahoo.com</email>
</row>
0 голосов
/ 02 мая 2011

XQuery 1.0 не имеет стандартного способа запрашивать отступ (или другое форматирование) результатов.Многие реализации XQuery имеют свои собственные механизмы.Например, если вы используете Saxon из командной строки, вы можете использовать опцию! Indent = yes.Я не знаю, какие опции предоставляет XMLSpy.

В XQuery 1.0 имеется опция «объявить сохранение границ пространства», которая приводит к тому, что пробел в запросе копируется в вывод;это может иметь тот эффект, который вам требуется, хотя, по моему опыту, он также может иметь нежелательные эффекты.

...