问题
Input:
<book>
<chapter href="..">
<topicref chunk="to-content" href"..">
</topicref>
<topicref chunk="to-content" href"..">
</topicref>
</chapter>
</book>
Output:
<book>
<chapter chunk="to-content" href="..">
<topicref href"..">
</topicref>
<topicref href"..">
</topicref>
</chapter>
</book>
I cannot use xsl:attribute name="chunk">to-content</xsl:attribute>
because it throws "creating an attribute here will fail if previous instructions create any children." warning and then error. I understand that as described here. Any workaround?
Using XSLT 2.0 with Saxon 9. (just getting the hang of XSLT/ S.O. still). Sorry if this is too broad but any help in any direction will be appreciated.
回答1:
In order to add an attribute to the chapter
element, it would be best to have a template matching the chapter
element - along the lines of:
<xsl:template match="chapter">
<xsl:copy>
<xsl:attribute name="chunk">to-content</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
Similarly, to remove the chunk
attribute from topicref
:
<xsl:template match="topicref/@chunk"/>
回答2:
Try this:
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="chapter">
<xsl:copy>
<!-- If the chapter contains a topicref with chunk="to-content", set chunk to-content on the chapter unless it's already there.-->
<xsl:if test=".//topicref/@chunk = 'to-content' and not(@chunk='to-content')">
<xsl:attribute name="chunk">to-content</xsl:attribute>
</xsl:if>
<!-- Copy all chapter attributes -->
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="topicref">
<xsl:copy>
<!-- Copy every attribute except chunk="to-content" -->
<xsl:copy-of select="@*[not(name() = 'chunk' and . = 'to-content')]"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
来源:https://stackoverflow.com/questions/31704005/xslt-moving-child-attribute-to-parent