如何修复难看的 XQuery 输出?

发布于 11-04 02:59 字数 2807 浏览 4 评论 0原文

这是我的 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>[email protected]</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"
              >[email protected]</Email>
    </email>
</row>

不过,我看到的所有示例都输出类似这样的内容:

<row>
    <first-name>Alexander</first-name>
    <last-name>Mart</last-name>
    <email>[email protected]</email>
</row>

如何像这样漂亮地格式化我的输出?

另外,为什么我的结果中会出现此

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

标签,而不是 ?有办法摆脱它吗?我在顶部附近添加了 declare default element namespace "http://www.example.com";,因为如果没有它,我的 XQuery 就无法工作。但如果这没有显示在我的结果中,那就太好了。

Here is my XML document:

<?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>[email protected]</Email>
</Student>
</Students>

I have this 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>

The output I am getting is:

<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"
              >[email protected]</Email>
    </email>
</row>

All the examples I see, though, output something like this:

<row>
    <first-name>Alexander</first-name>
    <last-name>Mart</last-name>
    <email>[email protected]</email>
</row>

How do I format my output prettily like this?

Also, why am I getting this

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

tag in my results, instead of just <first-name>? Is there a way to get rid of that? I added the declare default element namespace "http://www.example.com"; near the top because I couldn't get my XQuery to work without it. But it would be really nice if that wasn't getting displayed in my results.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

为你鎻心2024-11-11 02:59:33

使用

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>[email protected]</Email>
  </Student>
</Students>

生成了想要的结果

<row>
   <first-name>A</first-name>
   <last-name>Z</last-name>
   <email>[email protected]</email>
</row>

解释:文字结果元素(等)位于默认元素命名空间中。解决方案是不使用默认元素名称空间声明。

Use:

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> 

when this is applied to the following XML document (no XML document was provided by you!!!):

<Students  xmlns="http://www.example.com">
  <Student>
    <First-Name>A</First-Name>
    <Last-Name>Z</Last-Name>
    <Email>[email protected]</Email>
  </Student>
</Students>

the wanted result is produced:

<row>
   <first-name>A</first-name>
   <last-name>Z</last-name>
   <email>[email protected]</email>
</row>

Explanation: The literal result elements (row, etc.) are in the default element namespace. The solution is not to use default element namespace declaration.

心不设防2024-11-11 02:59:33

XQuery 1.0 没有请求结果缩进(或其他格式)的标准方法。许多 XQuery 实现都有自己的机制。例如,如果您从命令行使用 Saxon,则可以使用选项 !indent=yes。我不知道 XMLSpy 提供了哪些选项。

XQuery 1.0 中有一个选项“声明边界空间保留”,它会导致查询中的空格被复制到输出中;这可能会产生您需要的效果,但根据我的经验,它也可能会产生不需要的效果。

XQuery 1.0 does not have a standard way to request indentation (or other formatting) of results. Many XQuery implementations have their own mechanisms. For example, if you're using Saxon from the command line, you can use the option !indent=yes. I don't know what options XMLSpy provides.

There is an XQuery 1.0 option "declare boundary-space preserve" which causes whitespace in the query to be copied to the output; this might have the effect you require, though in my experience it can also have unwanted effects.

韶华倾负2024-11-11 02:59:33

首先,您的确切查询不应该产生该输出。您必须改用它(因为输入上的默认名称空间声明):

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"
              >[email protected]</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>[email protected]</email>
</row>

First, your exact query shouldn't be producing that output. You must be using this instead (because of the default namespace declaration on your input):

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>

That indeed output:

<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"
              >[email protected]</Email>
    </email>
</row>

WHY?: Because your sequence constructor { $firstName } output the node instace referenciated by $firstName not its string-value. That should be:

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>

Output:

<row xmlns="http://www.example.com">
    <first-name>Alexander</first-name>
    <last-name>Mart</last-name>
    <email>[email protected]</email>
</row>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文