XML-документ в HTML-документ с использованием XQuery - нужна помощь в замене тегов элементов - PullRequest
2 голосов
/ 28 ноября 2011

У меня есть документ XML, который я хотел бы преобразовать в HTML.Я использую Xquery с парсером кислорода для этого.

Это 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>

Что я хотел бы сделать сейчас, так это заменить компонентный тег предварительным тегом (с использованием пробелов для отступа), тег заголовка стег курсива и тег страниц с жирным тегом (в основном используются теги HTML вместо тегов XML, поэтому документ можно просматривать в веб-браузере).Я пытался использовать функцию замены, но не смог заставить ее работать.

Может кто-нибудь помочь, пожалуйста?

Спасибо:)

С уважением, Жанетт

Ответы [ 2 ]

5 голосов
/ 29 ноября 2011

Как отметил 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.

3 голосов
/ 28 ноября 2011

Один прямой путь (с использованием 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>

Надеюсь, это поможет, Кристиан

...