XSLT - преобразовать XML в результат ответа REST - PullRequest
1 голос
/ 02 декабря 2011

В настоящее время я пытаюсь использовать XSLT для преобразования некоторого псевдокода XML в результат ответа покоя

Например, со следующим xml:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:functions="http://foo.com/api/rest">
  <item bar="foo">some item</item>
  <functions:fetch a="3" b="foo" />
</root>

А если результат http://foo.com/services/rest/fetch/a/3/b/foo равен:

<?xml version="1.0" encoding="UTF-8"?>
<rsp stat="ok">
  <book>
    <title>Ethics</title>
  </book>
  <book>
    <title>Beyond Good and Evil</title>
  </book>
</rsp>

Результат синтаксического анализа XSLT, который я пытаюсь получить:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:functions="http://foo.com/api/rest">
  <item bar="foo">some item</item>
  <book>
    <title>Ethics</title>
  </book>
  <book>
    <title>Beyond Good and Evil</title>
  </book>
</root>

Я знаю, что могу использовать <xsl:value-of select="document('http://foo.com/services/rest/fetch/a/3/b/foo')"/> для выполнения запроса, но я застрял на том, как генерировать и обрабатывать его в том же XSLT.

Любая помощь будет принята с благодарностью, заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 02 декабря 2011

Вот одно из возможных чистых решений XSLT 1.0 :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:functions="http://foo.com/api/rest"
 exclude-result-prefixes="functions">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vDynPart">
  <xsl:for-each select="/*/functions:*/@*">
   <xsl:value-of select="concat('/', name(), '/', .)"/>
  </xsl:for-each>
 </xsl:variable>

 <xsl:variable name="vRes" select=
  "document(concat('http://foo.com/services/rest/fetch',
                   $vDynPart)
            )"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/">
  <xsl:copy>
   <xsl:copy-of select="@*"/>
   <xsl:apply-templates/>

   <xsl:apply-templates select="$vRes/*/node()"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="functions:*"/>
</xsl:stylesheet>
0 голосов
/ 02 декабря 2011

Благодаря ответу от Dimitre я нашел решение!

(я делаю новый ответ, немного настроив решение Dimitre для работы с любым именем функции и несколькими функциями в одном XML)

Здесь xslt:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:functions="http://foo.com/api/rest"
  exclude-result-prefixes="functions">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="functions:*">
    <xsl:variable name="request_function">
      <xsl:value-of select="local-name(.)"/>
    </xsl:variable>
    <xsl:variable name="request_parameters">
      <xsl:for-each select="@*">
        <xsl:value-of select="concat('/', name(), '/', .)"/>
      </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="rest_response" select="document(concat('http://foo.com/services/rest/', $request_function, $request_parameters) )"/>
    <xsl:apply-templates select="$rest_response/*/node()"/>
  </xsl:template>
</xsl:stylesheet>

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...