我跳過其中<TextContent>
變成<HtmlContent>
和<VisualContent id="n" />
成爲<img data-id="n" />
因爲這個問題是非常困難沒有這些分心的部分。
我選擇的方法查看名稱爲而不是的第一個前面的兄弟姐妹與當前元素的名稱相同。該同級的唯一ID是由同一個名字的相鄰的元件可以被分組的關鍵是:
<?xml version="1.0" encoding="utf-8"?>
<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:key name="prevByName" match="TextContent/*" use="generate-id(preceding-sibling::*[not(name()=name(current()))][1])" />
<xsl:template match="/">
<Article><TextContent>
<xsl:for-each select="Article/TextContent/*[generate-id()=generate-id(key('prevByName', generate-id(preceding-sibling::*[not(name()=name(current()))][1]))[1])]">
<xsl:variable name="myGroup" select="key('prevByName', generate-id(preceding-sibling::*[not(name()=name(current()))][1]))" />
<xsl:choose>
<xsl:when test="count($myGroup) > 1">
<ul>
<xsl:for-each select="$myGroup">
<li><xsl:copy-of select="."/></li>
</xsl:for-each>
</ul>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</TextContent></Article>
</xsl:template>
</xsl:stylesheet>
當施加到您的輸入例如,下面的結果產生:
<?xml version="1.0" encoding="utf-8"?>
<Article>
<TextContent>
<p>lorem</p>
<ul>
<li>
<VisualContent id="1"/>
</li>
<li>
<VisualContent id="2"/>
</li>
<li>
<VisualContent id="3"/>
</li>
</ul>
<p>ipsum</p>
<VisualContent id="4"/>
<p>dolor</p>
<VisualContent id="5"/>
</TextContent>
</Article>
編輯: 這裏的一個修改的版本,只有組相鄰 「VisualContent」 元素:
<?xml version="1.0" encoding="utf-8"?>
<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:key name="prevByName" match="TextContent/*" use="generate-id(preceding-sibling::*[not(name()=name(current()))][1])" />
<xsl:template match="/Article/TextContent">
<Article><TextContent>
<xsl:apply-templates select="*"/>
</TextContent></Article>
</xsl:template>
<xsl:template match="TextContent/*[not(self::VisualContent)]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="VisualContent[generate-id()=generate-id(key('prevByName', generate-id(preceding-sibling::*[not(name()=name(current()))][1]))[1])]">
<xsl:variable name="myGroup" select="key('prevByName', generate-id(preceding-sibling::*[not(name()=name(current()))][1]))" />
<xsl:choose>
<xsl:when test="count($myGroup) > 1">
<ul>
<xsl:for-each select="$myGroup">
<li><xsl:copy-of select="."/></li>
</xsl:for-each>
</ul>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
這很可能使用了一些精簡,但我認爲原則是清楚的,我需要得到一些睡眠...
我想了解您的代碼,但是我們可以在沒有的情況下執行此操作,並且僅使用模板?因爲我學到的是在XSLT中使用模板是一種經典的方式。無論如何,謝謝你的解決方案。它演示了很多東西 –
spiderman
這有助於很多,謝謝@ michael.hor257k!有沒有一種方法可以讓這個只將相鄰的「VisualContent」元素分組?例如,我使用的輸入的某些部分有相鄰的「p」標籤,但我不希望那些顯示在ul中的標籤。 – sauceboat
@sauceboat我在回答中添加了修改後的版本。 –