[英]Xslt transformation for renaming parent and child nodes
我正在將 xsl 模板處理為 append 與標簽名稱相反。 但是下面的模板沒有按預期工作。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<!-- identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="MAINS">
<xsl:copy>
<xsl:apply-templates select="*[not(self::MAIN)]" />
<xsl:apply-templates select="MAIN" />
</xsl:copy>
</xsl:template>
<xsl:template match="*[starts-with(local-name(), 'MAINS/MAIN')]">
<xsl:copy>
<xsl:apply-templates select="SUBMAIN" />
</xsl:copy>
</xsl:template>
<xsl:template match="//SUBMAINS">
<xsl:copy>
<xsl:apply-templates select="*[not(self::SUBMAIN)]" />
<xsl:apply-templates select="SUBMAIN" />
</xsl:copy>
</xsl:template>
<xsl:template match="MAIN|SUBMAIN">
<xsl:element name="{concat(local-name(),position())}">
<xsl:copy-of select="*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
輸入如下:
<TEST>
<TAG1>
xyz
</TAG1>
<MAINS>
<MAIN>
<DAT>abc</DAT>
<SUBMAIN>
<DAT2>123</DAT2>
</SUBMAIN>
<SUBMAIN>
<DAT2>456</DAT2>
</SUBMAIN>
</MAIN>
<MAIN>
<DAT>pqr</DAT>
<SUBMAIN>
<DAT2>123</DAT2>
</SUBMAIN>
<SUBMAIN>
<DAT2>789</DAT2>
</SUBMAIN>
</MAIN>
<MAIN>
<DAT>mno</DAT>
</MAIN>
</MAINS>
<SUBMAINS>
<SUBMAIN>
<DAT2>789</DAT2>
<DAT3>sfsfd</DAT3>
</SUBMAIN>
<SUBMAIN>
<DAT2>789</DAT2>
<DAT3>dsdsd</DAT3>
</SUBMAIN>
</SUBMAINS>
</TEST>
預期的 output 如下所示,其中標簽 SUBMAIN 或 MAIN 應重命名為 SUBMAIN 或 MAIN 並附加索引/位置:
<TEST>
<TAG1>
xyz
</TAG1>
<MAINS>
<MAIN1>
<DAT>abc</DAT>
<SUBMAIN1>
<DAT2>123</DAT2>
</SUBMAIN1>
<SUBMAIN2>
<DAT2>456</DAT2>
</SUBMAIN2>
</MAIN1>
<MAIN2>
<DAT>pqr</DAT>
<SUBMAIN1>
<DAT2>123</DAT2>
</SUBMAIN1>
<SUBMAIN2>
<DAT2>789</DAT2>
</SUBMAIN2>
</MAIN2>
<MAIN3>
<DAT>mno</DAT>
</MAIN3>
</MAINS>
<SUBMAINS>
<SUBMAIN1>
<DAT2>789</DAT2>
<DAT3>sfsfd</DAT3>
</SUBMAIN1>
<SUBMAIN2>
<DAT2>789</DAT2>
<DAT3>dsdsd</DAT3>
</SUBMAIN2>
</SUBMAINS>
</TEST>
但實際的 output 是:
<TEST>
<TAG1>
xyz
</TAG1>
<MAINS>
<MAIN1>
<DAT>abc</DAT>
<SUBMAIN>
<DAT2>123</DAT2>
</SUBMAIN>
<SUBMAIN>
<DAT2>456</DAT2>
</SUBMAIN>
</MAIN1>
<MAIN2>
<DAT>pqr</DAT>
<SUBMAIN>
<DAT2>123</DAT2>
</SUBMAIN>
<SUBMAIN>
<DAT2>789</DAT2>
</SUBMAIN>
</MAIN2>
<MAIN3>
<DAT>mno</DAT>
</MAIN3>
</MAINS>
<SUBMAINS>
<SUBMAIN1>
<DAT2>789</DAT2>
<DAT3>sfsfd</DAT3>
</SUBMAIN1>
<SUBMAIN2>
<DAT2>789</DAT2>
<DAT3>dsdsd</DAT3>
</SUBMAIN2>
</SUBMAINS>
</TEST>
在實際結果中,MAIN 下的 SUBMAIN 標簽沒有附加數字。
AFAICT,這將返回預期結果:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="MAIN">
<xsl:element name="MAIN{position()}">
<xsl:apply-templates select="*[not(self::SUBMAIN)]"/>
<xsl:apply-templates select="SUBMAIN"/>
</xsl:element>
</xsl:template>
<xsl:template match="SUBMAIN">
<xsl:element name="SUBMAIN{position()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
添加:
這是您可以查看的另一種方式:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="MAIN | SUBMAIN">
<xsl:variable name="n">
<xsl:number/>
</xsl:variable>
<xsl:element name="{name()}{$n}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
首先,這個模板永遠不會匹配:
<xsl:template match="*[starts-with(local-name(), 'MAINS/MAIN')]">
那是因為沒有 NCName 可以有'/'
字符。
其次,這個樣式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*"/>
<!-- identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="MAINS">
<xsl:copy>
<xsl:apply-templates select="*[not(self::MAIN)]" />
<xsl:apply-templates select="MAIN" />
</xsl:copy>
</xsl:template>
<xsl:template match="SUBMAINS">
<xsl:copy>
<xsl:apply-templates select="*[not(self::SUBMAIN)]" />
<xsl:apply-templates select="SUBMAIN" />
</xsl:copy>
</xsl:template>
<xsl:template match="MAIN|SUBMAIN">
<xsl:variable name="position">
<xsl:number/>
</xsl:variable>
<xsl:element name="{local-name()}{$position}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?>
<TEST>
<TAG1>
xyz
</TAG1>
<MAINS>
<MAIN1>
<DAT>abc</DAT>
<SUBMAIN1>
<DAT2>123</DAT2>
</SUBMAIN1>
<SUBMAIN2>
<DAT2>456</DAT2>
</SUBMAIN2>
</MAIN1>
<MAIN2>
<DAT>pqr</DAT>
<SUBMAIN1>
<DAT2>123</DAT2>
</SUBMAIN1>
<SUBMAIN2>
<DAT2>789</DAT2>
</SUBMAIN2>
</MAIN2>
<MAIN3>
<DAT>mno</DAT>
</MAIN3>
</MAINS>
<SUBMAINS>
<SUBMAIN1>
<DAT2>789</DAT2>
<DAT3>sfsfd</DAT3>
</SUBMAIN1>
<SUBMAIN2>
<DAT2>789</DAT2>
<DAT3>dsdsd</DAT3>
</SUBMAIN2>
</SUBMAINS>
</TEST>
注意:兩條規則用於重新排序MAINS
和SUBMAINS
子元素,一條規則用於按照“推送”的順序枚舉MAIN
和SUBMAIN
元素。
附錄:枚舉元素名稱不是一個好主意,因為幾乎沒有 SGML/XML 詞匯表將其用於兄弟姐妹(HTML 中的標題是例外,但它們在線性文本上的 model 層次結構)
編輯:有一個原因,因為我不喜歡推送風格,那就是在上下文(當前節點、當前上下文列表、當前位置)上進行中繼。 它有時會使代碼錯誤變得難以處理。 對於“確定性”編號,請使用xsl:number
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.