[英]Use XSLT to transform XML with conditionals upon node count
我試圖從XML文件中刪除節點。 我只需要為每個XML使用一個XSLT,我需要根據document元素的子節點數在XSLT中做出決策。
<root>
<branch>
<foo>bar</foo>
</branch>
<root>
應該變成
<branch>
</branch>
但
<root>
<branch>
<foo>bar</foo>
</branch>
<branch>
<foo>baz</foo>
<root>
成
<root>
<branch>
</branch>
<branch>
</branch>
<root>
也就是說,如果根元素的(僅)子元素在應用XSLT后可以充當結果XML的新文檔根,則應該刪除它。 必須在每次出現時刪除<foo>
節點。
有沒有辦法用單個XSL執行此操作?
嘗試
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root[*[2]]">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="root[* and not(*[2])]">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="branch/foo"/>
更簡單,更短,更通用(沒有元素名稱硬編碼)的解決方案 :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*[not(*[2])]">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="/*/*/node()"/>
</xsl:stylesheet>
當此轉換應用於第一個提供的XML文檔 (更正為格式良好)時:
<root>
<branch>
<foo>bar</foo>
</branch>
</root>
產生了想要的正確結果 :
<branch></branch>
當對第二個提供的XML文檔應用相同的轉換時 (再次需要針對格式良好進行更正):
<root>
<branch>
<foo>bar</foo>
</branch>
<branch>
<foo>baz</foo>
</branch>
</root>
再次生成所需的正確輸出 :
<root>
<branch></branch>
<branch></branch>
</root>
說明 :
身份規則 “按原樣”復制每個節點。
有兩個模板覆蓋特定節點的標識模板,並以不同方式處理這些節點。
第一個覆蓋模板匹配沒有第二個元素子元素的頂部元素。 它不會復制元素本身,而是處理其子元素。
第二個覆蓋模板匹配作為頂部元素的祖母的任何元素。 此模板沒有正文,這意味着所有這樣的匹配元素都會被忽略並且不包含在輸出中(換句話說 - “已刪除”)
請注意 :
此轉換可以應用於任何 XML文檔,無論其中的元素名稱如何,仍然可以生成所需的正確結果。
例如 ,在應用於此XML文檔時:
<t>
<b>
<f>brrr</f>
</b>
<b>
<f>bzzz</f>
</b>
</t>
產生了想要的正確結果 :
<t>
<b></b>
<b></b>
</t>
將此與當前接受的答案產生的結果進行對比 :
<t>
<b>
<f>brrr</f>
</b>
<b>
<f>bzzz</f>
</b>
</t>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.