我想將XML文檔轉換爲HTML。一些XML元素有聯繫的其他文件,如:如何生成唯一的字符串
<link href="1.html">
在HTML輸出,我想:
<a href="1.html&no_cache={unique_id}">
我怎麼能產生這種獨特的相當大的ID?
我想將XML文檔轉換爲HTML。一些XML元素有聯繫的其他文件,如:如何生成唯一的字符串
<link href="1.html">
在HTML輸出,我想:
<a href="1.html&no_cache={unique_id}">
我怎麼能產生這種獨特的相當大的ID?
首先,我假設由於某些未知原因,您無法使用link
中的絕對URL作爲所需的UID--這是最簡單也是最自然的解決方案。
如果我的假設是正確的,那麼:
這是XSLT一件容易的事。
由於OP希望生成的id在執行多次轉換時是相同的,因此不適合使用generate-id()
函數。
這裏是產生穩定的IDS的一個簡單的方法:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<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="link[@href]">
<xsl:variable name="vUid">
<xsl:number level="any" count="link[@href]"/>
</xsl:variable>
<a href="{@href}&no_cache={{{$vUid}}}"/>
</xsl:template>
</xsl:stylesheet>
當這種轉變是在下面的XML文檔應用(不管多少次):
<t>
<link href="1.html"/>
<a>
<link href="2.html"/>
<b>
<link href="3.html"/>
<c>
<link href="4.html"/>
</c>
<link href="5.html"/>
</b>
<link href="6.html"/>
<d>
<link href="7.html"/>
</d>
</a>
<link href="8.html"/>
<e>
<link href="9.html"/>
</e>
<link href="10.html"/>
</t>
每次都要生成相同的正確結果:
<t>
<a href="1.html&no_cache={1}"/>
<a>
<a href="2.html&no_cache={2}"/>
<b>
<a href="3.html&no_cache={3}"/>
<c>
<a href="4.html&no_cache={4}"/>
</c>
<a href="5.html&no_cache={5}"/>
</b>
<a href="6.html&no_cache={6}"/>
<d>
<a href="7.html&no_cache={7}"/>
</d>
</a>
<a href="8.html&no_cache={8}"/>
<e>
<a href="9.html&no_cache={9}"/>
</e>
<a href="10.html&no_cache={10}"/>
</t>
請注意:使用<xsl:number>
來產生id。
如果同一個鏈接可以出現在文件中幾次,我們需要所有出現使用相同的ID,這裏是這個問題解決方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kHrefByVal" match="link/@href" use="."/>
<xsl:variable name="vUniqHrefs" select=
"//link/@href
[generate-id()
=
generate-id(key('kHrefByVal',.)[1])
]
"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="link[@href]">
<xsl:variable name="vthisHref" select="@href"/>
<xsl:variable name="vUid">
<xsl:for-each select="$vUniqHrefs">
<xsl:if test=". = $vthisHref">
<xsl:value-of select="position()"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<a href="{@href}&no_cache={{{$vUid}}}"/>
</xsl:template>
</xsl:stylesheet>
當這種轉化應用上下面的XML文檔:
<t>
<link href="1.html"/>
<a>
<link href="2.html"/>
<b>
<link href="1.html"/>
<c>
<link href="3.html"/>
</c>
<link href="2.html"/>
</b>
<link href="1.html"/>
<d>
<link href="3.html"/>
</d>
</a>
<link href="4.html"/>
<e>
<link href="2.html"/>
</e>
<link href="4.html"/>
</t>
想要的,正確的結果產生:
<t>
<a href="1.html&no_cache={1}"/>
<a>
<a href="2.html&no_cache={2}"/>
<b>
<a href="1.html&no_cache={1}"/>
<c>
<a href="3.html&no_cache={3}"/>
</c>
<a href="2.html&no_cache={2}"/>
</b>
<a href="1.html&no_cache={1}"/>
<d>
<a href="3.html&no_cache={3}"/>
</d>
</a>
<a href="4.html&no_cache={4}"/>
<e>
<a href="2.html&no_cache={2}"/>
</e>
<a href="4.html&no_cache={4}"/>
</t>
嘗試generate-id()。
<xsl:value-of select="generate-id(.)"/>
這裏是一個進一步的解釋:http://www.w3schools.com/XSL/func_generateid.asp
XSLT是一種功能性的語言,這意味着對於給定輸入它將總是產品相同的輸出,所以通過定義一個GUID方法或任何其他隨機發生器就不會成爲設計規範的一部分。你最好的選擇是,如果你的客戶端綁定的是使用時間相關的方法作爲generate-id的僞隨機種子的一部分,但是由於你的目標似乎很強,所以你應該放棄這個,只關注應用正確的反緩存標題到您正在嘗試保護的資源。
這是不可能用純XSLT,但一些替代方案可能是:
<a href="1.html&no_cache={myns:unique_id()}">
。這會給你你想要的結果,但是取決於你用來執行轉換的框架的支持。
[generate-id()](http://www.w3schools.com/XSL/func_generateid.asp)。 – khachik 2010-12-22 13:36:26
不適合我的情況。如果我嘗試多次處理這個xml,generate-id()不會生成唯一的ID。我想每次都有唯一的ID – Nawa 2010-12-22 14:20:57
好問題,+1。查看我的答案,獲取完整而簡短的XSLT解決方案。 :) – 2010-12-22 16:19:33