3
假設有與內容模型中的元件如下:當兄弟元素任意存在時,XSLT按順序創建元素?
<!ELEMENT wrapper (a*,b*,c*,d*,e*,f*,g*,h*,i*,j*,k*,l*,m*,n*,o*,p*,q*,r*,s*,t*,u*,v*,w*,x*,y*,z*)>
換言之,一個包裝元件內有可能存在任意子元素的指定順序。
您需要在包裝中創建一個新元素(例如m),同時保留已經存在的元素並確保輸出符合內容模型。
這是排序的溶液:
<xsl:template match="@*|node()">
<xsl:sequence select="."/>
</xsl:template>
<xsl:template match="wrapper">
<xsl:copy>
<xsl:apply-templates select="a,b,c,d,e,f,g,h,i,j,k,l,m"/>
<m>This is new</m>
<xsl:apply-templates select="n,o,p,q,r,s,t,u,v,w,x,y,z"/>
</xsl:copy>
</xsl:template>
然而,這種方案將降低包裝元素之內的所有的空格,註釋或處理指令。我已經想出了一些解決方案,不會丟棄那些東西,但沒有任何我很滿意的解決方案。
什麼是這個問題最優雅的解決方案,不會丟棄節點? XSLT 3和架構感知解決方案都很好。
下面是一些例子輸入和輸出:
<!-- Input -->
<wrapper/>
<!-- Output -->
<wrapper><m>This is new</m></wrapper>
<!-- Input -->
<wrapper><a/><z/></wrapper>
<!-- Output -->
<wrapper><a/><m>This is new</m><z/></wrapper>
<!-- Input -->
<wrapper><m/></wrapper>
<!-- Output -->
<wrapper><m/><m>This is new</m></wrapper>
<!-- Input -->
<wrapper>
<a/>
<!-- put m here -->
<z/>
</wrapper>
<!-- Output -->
<!-- NB: The comment and whitespace could come after the inserted element instead. This case is ambiguous -->
<wrapper>
<a/>
<!-- put m here --><m>This is new</m>
<z/>
</wrapper>
<!-- Input -->
<wrapper>
<a/>
<b/>
<c/>
<n/>
<o/>
<!-- p is not here -->
<?do not drop this?>
</wrapper>
<!-- Output -->
<wrapper>
<a/>
<b/>
<c/><m>This is new</m>
<n/>
<o/>
<!-- p is not here -->
<?do not drop this?>
</wrapper>
這不是關鍵的是插入的元素周圍非元素節點之前或之後來到,只是他們沒有丟棄,它們相對於順序原始元素被保留。
您可以指示模板/秒匹配子元素以複製任何尾隨(或領先)文本,註釋或處理指令點頭ES。 - P.S.這[mcve]可能會有用。 –
@Danielhaley'm'可能不存在,因爲我理解 –