2015-03-31 33 views
1

我給低於我XPROC管道的目標是把源XML文檔中,運行2 XSLT與<p:xslt>步驟變換,然後是第二<p:xslt>到喂入後,該輸出XML在<p:http-request>步驟<c:body>飼餵<p:xslt>輸出到HTTP PUT請求的<c:body>在XPROC

<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" 
    xmlns:c="http://www.w3.org/ns/xproc-step" 
    version="1.0"> 

    <p:input port="source" primary="true"/> 
    <p:output port="result" primary="true"/> 

    <p:serialization port="result" 
        indent="false" 
        method="xml" 
        encoding="utf-8" 
        omit-xml-declaration="false" 
        doctype-system="myDTD.dtd" 
        doctype-public="-//DOCTYPE-HERE"/> 

    <p:xslt> 
    <p:input port="stylesheet"> 
     <p:document href="XSLT-1.xslt"/> 
    </p:input> 
    </p:xslt> 

    <p:xslt> 
    <p:input port="stylesheet"> 
     <p:document href="XSLT-2.xslt"/> 
    </p:input> 
    </p:xslt> 

    <p:http-request omit-xml-declaration="false" 
        encoding="UTF-8"> 
    <p:input port="source"> 
     <p:inline> 
     <c:request href="http://localhost:80/myRESTserver/dburi/myDOC.xml" 
        auth-method="basic" 
        username="user" 
        password="admin" 
        method="put"> 
      <c:body content-type="text/xml" > 

      </c:body> 
     </c:request> 
     </p:inline> 
    </p:input> 
    </p:http-request> 

有沒有辦法來實現這一目標?當我嘗試按原樣執行此代碼時,首先調用<p:http-request>(將空XML文件抽取到數據庫中)。

回答

3

p:http-request首先運行的原因是它不依賴於管道中的任何其他步驟。的p:http-requestsource輸入端口被綁定到一個靜態內嵌c:request文件,因此步驟不需要等待任何其他步驟,以先完成。因此該步驟可以隨時運行。

要解決該問題,您需要將輸入端口p:http-request連接到第二個步驟p:xslt。這可以明確地使用(使用p:pipe)或隱式地(依靠XProc處理器將自動生成隱含的p:pipe連接的事實)。我們來演示都在解決的過程中的主要問題(嵌入p:xslt的輸出c:body):

嵌入在XML封裝XML內容,通常去到XPROC步驟p:wrapp:wrap-sequence。但是,它們使用簡單的(一級)XML包裝元素,所以如果您想要打包多個XML級別(如您的案例:c:request/c:body),它們並不是那麼有用。所以,你必須使用別的東西 - 例如p:insert步:

... 
<p:xslt name="xslt2"> 
    <p:input port="stylesheet"> 
    <p:document href="XSLT-2.xslt"/> 
    </p:input> 
</p:xslt> 
<p:insert match="c:request/c:body" position="first-child"> 
    <p:input port="source"> 
    <p:inline> 
     <c:request href="http://localhost:80/myRESTserver/dburi/myDOC.xml" 
       auth-method="basic" 
       username="user" 
       password="admin" 
       method="put"> 
     <c:body content-type="text/xml"> 
     </c:body> 
     </c:request> 
    </p:inline> 
    </p:input> 
    <p:input port="insertion"> 
    <p:pipe step="xslt2" port="result"/> 
    </p:input> 
</p:insert> 
<p:http-request omit-xml-declaration="false" 
       encoding="UTF-8"/> 
... 

讓我們來看看這是什麼一樣:

  1. 我們給了第二p:xslt步驟名(xslt2)。
  2. 我們在第二步p:xslt步驟和p:http-request步驟之間放置了一個p:identity步驟。 p:identity步驟使用靜態文件c:request/c:body作爲插入目標,並將名爲xslt2的步驟的輸出用作要插入的內容。它將插入內容作爲c:request/c:body的第一個孩子。
  3. 我們移除了p:http-requestsource輸入端口的靜態連接。這很好,因爲p:insert步驟的輸出將自動流入source輸入端口p:http-request
+0

是從P:http-request中取出並放在p:insert步驟內的C:請求?現在Xproc說p:insert不能包含c:request – Laterade 2015-04-02 20:50:05

+0

是的,'c:request'是從'p:http-request'中取出的。你得到錯誤是因爲我忘記將'c:request'包裝在'p:inline'中 - 我只是在我的文章中修復了這個錯誤。 – 2015-04-13 08:16:47

+0

@VojtěchToman我有一個類似的用例(但有一個'http-request'步驟,接着是'xquery'步驟,然後是另一個'http-request')。按照建議,當我嘗試添加'p:insert'步驟時,出現一個錯誤(在XML Calabash中):「無法評估表達式:前綴c尚未聲明。」應在哪裏聲明前綴? – tat 2015-10-19 12:11:25