使用XQuery将XML文档转换为HTML文档 - 需要帮助替换元素标记

时间:2011-11-28 18:09:28

标签: xml xhtml xquery

我有一个XML文档,我想将其转换为HTML。我正在使用Xquery和Oxygen解析器。

这是xml:

<?xml version="1.0" encoding="UTF-8"?>
<?oxygen RNGSchema="file:textbook.rnc" type="compact"?>
<books xmlns="books">

    <book ISBN="i0321165810" publishername="OReilly">
        <title>XPath</title>
        <author>
            <name>
                <fname>Priscilla</fname>
                <lname>Warnley</lname>
            </name>
            <address>
                <street_address>Hill Park<street_address>
                <zip>90210</zip>
                <state>california</state>
            </address>
            <phone>00000000</phone>
            <e-mail>priscilla@oreilly.com</e-mail>
        </author>
        <year>2007</year>
        <field>Databases</field>
        <TOC>
            <component>
                <type>Part</type>
                <title>Xpath</title>
                <component>
                    <title>Chapter... A tour of xquery</title>
                    <pages>3</pages>
                    <component>
                        <title>Introductions</title>
                    </component>
                    <component>
                        <title>Getting started</title>
                    </component>
                </component>
            </component>
        </TOC>
    </book>

    <publisher publishername="OReilly">
        <web-site>www.oreilly.com</web-site>
        <address>
            <street_address>hill park</street_address>
            <zip>90210</zip>
            <state>california</state>
        </address>
        <phone>400400400</phone>
        <e-mail>oreilly@oreilly.com</e-mail>
        <contact>
            <field>Databases</field>
            <name>
                <fname>Anna</fname>
                <lname>Smith</lname>
            </name>
        </contact>
    </publisher>
</books>

我首先执行此Xquery查询:

declare default element namespace "books";
<html>
<head> 
<title>Table of contents</title>
</head>
<body>
<b>Table of contents</b>
<hr/>
{   for $i in //book[@ISBN='i0321165810']/TOC
    return $i
}
</body>
</html>

根据我的xml文档得到以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="Books">
   <head>
      <title>Table of content</title>
   </head>
   <body>
      <b>TOC</b>
  <hr/>
      <TOC>
            <component> 
                <type>Part</type>
                <title>Foundations</title>
                <component>
                    <title>Chapter... A tour of xquery</title>
                    <pages>3</pages>
                    <component>
                        <title>Introductions</title>
                    </component>
                    <component>
                        <title>Getting started</title>
                    </component>
                </component>
            </component>
        </TOC>
   </body>
</html>

我现在要做的是用pre标签替换组件标签(使用缩进空格),带斜体标签的title标签和带粗体标签的pages标签(基本上使用HTML标签而不是XML标签) ,因此可以在Web浏览器中查看文档)。我试图使用替换功能,但我无法让它工作。

有人可以帮忙吗?

谢谢:)

祝你好运, 珍

2 个答案:

答案 0 :(得分:5)

正如DevNull所说,这是XSLT会发光的任务。这是我的XQuery解决方案:

declare default element namespace "http://www.w3.org/1999/xhtml";

declare function local:rename($node) {
  let $old-name := local-name($node)
  let $new-name :=
    switch($old-name)
      case 'component' return 'pre'
      case 'title'     return 'i'
      case 'pages'     return 'b'
      default          return $old-name
  return element { $new-name } {
    $node/@*,
    for $nd in $node/child::node()
    return if($nd instance of element())
      then local:rename($nd)
      else $nd
  }
};

<html>
  <head> 
     <title>Table of contents</title>
  </head>
  <body>
      <b>Table of contents</b>
      <hr/>
      {   for $i in //*:book[@ISBN='i0321165810']/*:TOC/*
          return local:rename($i)
      }
  </body>
</html>

函数local:rename($node)递归地下降到XML片段,重建它并替换元素名称。它既不优雅也不高效,但它应该能够胜任。

我还更改了default element namespace,因为您返回的XHTML文档位于books命名空间中。

答案 1 :(得分:3)

一种直接的方式(使用XQuery Update)如下所示:

declare default element namespace "books";
<html>
<head> 
<title>Table of contents</title>
</head>
<body>
<b>Table of contents</b>
<hr/> {
  copy $c := //book[@ISBN='i0321165810']/TOC
  modify (
    for $n in $c//component return rename node $n as 'tab',
    for $n in $c//title return rename node $n as 'i',
    for $n in $c//pages return rename node $n as 'b'
  )
  return $c     
}</body>
</html>

希望这有帮助, 基督教