2017-04-02 24 views
0

考慮下面的樣式表具有副本的XSLT和基本URI - 爲什麼uri會從XML文件更改爲XSLT文件?

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template name="start"> 
     <base-uris> 
      <node-base-uri> 
       <xsl:value-of select="base-uri(.)" /> 
      </node-base-uri> 
      <node-base-uri-from-copy> 
       <xsl:variable name="doc"> 
        <xsl:copy-of select="." /> 
       </xsl:variable> 
       <xsl:value-of select="base-uri($doc)" /> 
      </node-base-uri-from-copy> 
     </base-uris> 
    </xsl:template> 

</xsl:stylesheet> 

用下面的命令在命令行轉化任意的XML文件與撒克遜人後:

java net.sf.saxon.Transform -s:xml/index.xml -xsl:xsl/base-uri.xsl -it:start 

我預料的一樣值指向XML基礎的URI源文件。但第二種情況下的基本URI(帶有copy-of)指向XSLT文件。

<base-uris> 
    <node-base-uri>file:/xml/index.xml</node-base-uri> 
    <node-base-uri-from-copy>file:/xsl/base-uri.xsl</node-base-uri-from-copy> 
</base-uris> 

動機:在「現實世界中的樣式表」我用一個模板中包含其他XML源。它們在源XML本身中指定(href屬性中的相對路徑)。

<xsl:template match="include" mode="includes"> 
    <xsl:copy-of select="document(@href, .)/*"/> 
</xsl:template> 

Spec

節點的基礎URI被複制,除了在具有XML元素節點的情況下:base屬性

我問題:

首先,我會l瞭解如何從XML文件保留/設置/複製基本URI,而不是從XSLT文件中複製基本URI。

其次,我不明白規範和/或不明白xml:base屬性的東西。我只是想:我的代碼中沒有看到任何xml:base屬性,所以應該複製節點的基本URI。

最後一句話:

玩的時候,我想出了這樣的事情,感覺笨拙或乾脆錯誤的方式去:

<node-base-uri-work-around> 
    <xsl:variable name="doc"> 
     <wrapper> 
      <xsl:attribute name="xml:base" select="base-uri(.)" /> 
      <xsl:copy-of select="." /> 
     </wrapper> 
    </xsl:variable> 
    <xsl:value-of select="base-uri($doc/wrapper)" /> 
</node-base-uri-work-around> 
+1

考慮準確地解釋你正在做什麼來運行轉換,你只發布了帶有命名模板的XSLT 3樣式表,而沒有顯示任何輸入XML,也沒有解釋如何運行轉換,這對於理解並告訴你的輸入來自哪裏以及如何知道/確定基本URI。至於使用'',爲什麼不簡單使用''? –

+0

感謝Martin Honnen。只是在問題中提供了缺失的信息。是的,愚蠢的,爲什麼我只是不只是選擇文件?現在它工作正常。 – Stefan

回答

2

對於理解

  <xsl:variable name="doc"> 
       <xsl:copy-of select="." /> 
      </xsl:variable> 

查看https://www.w3.org/TR/xslt-30/#temporary-trees其中說:

的構建:

<xsl:variable name="tree"><a/></xsl:variable>

可視爲的縮寫:

<xsl:variable name="tree" as="document-node()"><xsl:document validation="preserve"><a/></xsl:document></xsl:variable>

,然後解釋,「文檔節點的基URI被取從樣式表中變量綁定元素的基本URI。「。這就解釋了爲什麼在這種情況下基URI是樣式表URI。如果你想改變,你可以根據需要在xsl:variable綁定元素上使用​​。

我目前不確定<xsl:copy-of select="document(@href, .)/*"/>與您首先在您的問題中描述的問題有關,您將不得不詳細說明在這種情況下您遇到基本URI問題的位置/方式。

+0

感謝Martin Honnen。這就是解釋。一件小事,只是爲了理解一切:'xsl:variable'的綁定元素是什麼?它是''嗎?如果是,則設置'xml:base'不會更改複製節點的基本URI。 – Stefan

+0

關於你評論的第二部分@Martin Honnen:''xsl:copy-of select =「document('some/rel/path/file.xml',。)/ *」/>'現在如預期的那樣起作用。所以我現在完全高興。也許我會發布這些天的另一個問題,關於在轉換過程中可能包含額外的xml文件。 – Stefan

+0

規範說「文檔節點的基本URI取自變量綁定元素的基本URI」,這意味着(隱式或顯式)'xsl:document'的基本URI取自'xsl:variable' 。 –

2

我不知道如何解釋「爲什麼?」的問題。一種解釋是「在規範中哪裏說這應該發生?」另一種解釋是「規範的作者爲什麼決定讓它按照這種方式行事?」

Martin Honnen指出了規範中指定使用xsl:variable創建爲臨時樹的文檔的基本URI的部分。至於爲什麼它是這樣設計的:那麼,歷史上準確的答案就需要通過檔案進行大量的拖網,即使這樣也很困難,因爲很多時候答案很簡單,就是沒有人提出任何替代方案。 XSLT 1.0表示每個節點都有一個基本URI,但據我所知,它沒有說明構造節點的基本URI應該是什麼;這是在XSLT 2.0中添加的。我不認爲使用xsl:變量構造的文檔節點的基本URI實際上可能不是樣式表基本URI(此時沒有其他東西真的可用),但5.7.1中的規則(構造複雜內容)規則10「複製元素或處理指令節點時,其基本URI屬性將更改爲與其新父項相同,除非它具有覆蓋此屬性的xml:base屬性(請參閱[XML Base])。」當然可以用不同的方式寫,我認爲這個選擇很有可能被辯論出來,但是到目前爲止我還記得那些論點。這是坦率的一點,因爲最終結果樹的最可能的形式是序列化的XML或DOM,並且都不會保留節點的基本URI。

+0

謝謝你這個有趣的解釋邁克爾凱。其實,我只是要求「規範中的哪些地方」和「請解釋規範的這部分,我不明白」。作爲XSLT的「初學者」,我無法對規範提出質疑。但在這個初學者層面上,我認爲用xsl:copy-of/xsl:variable構造一個文檔節點並保留/複製「源文檔節點」中的基本URI也是多麼直觀。 – Stefan

+0

任何人如果對複雜而模糊的base-uri概念提出疑問,就會被取消參考資格作爲「非常初學者」的資格;-) –