跨越兄弟元素的孩子分组

时间:2014-07-24 11:50:35

标签: xslt idml

我正在使用XSLT处理IDML文件。在从InDesign导出的IDML中,它将相同样式的连续段落一起运行,由<Br/>标记分隔,如下所示(我的输入XML):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Story>
    <ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/para">
        <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]">
            <Content>All rights reserved. No part of this publication may be reproduced in any material form (including photocopying or storing it in any medium by electronic means and whether or not transiently or incidentally to some other use of this publication) without the written permission of the copyright owner except in accordance with the provisions of the Copyright, Designs and Patents Act 1988 or under the terms of a licence issued by the </Content>
        </CharacterStyleRange>
        <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/italic">
            <Content>Copyright Licensing Agency Ltd, Saffron House, 6-10 Kirby Street, London, EC1N 8TS England</Content>
        </CharacterStyleRange>
        <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]">
            <Content>. Applications for the copyright owner’s written permission to reproduce any part of this publication should be addressed to the publisher.</Content>
            <Br/>
            <Content>Warning: The doing of an unauthorised act in relation to a copyright work may result in both a civil claim for damages and criminal prosecution.</Content>
            <Br/>
            <Content>Crown copyright material is reproduced with the permission of the Controller of HMSO and the Queen’s Printer for Scotland.</Content>
            <Br/>
        </CharacterStyleRange>
    </ParagraphStyleRange>
</Story>

现在,我需要将其转换为XML,看起来像这样

<?xml version="1.0" encoding="UTF-8"?>
<story> 
    <para>All rights reserved. No part of this publication may be reproduced in any material form (including photocopying or storing it in any medium by electronic means and whether or not transiently or incidentally to some other use of this publication) without the written permission of the copyright owner except in accordance with the provisions of the Copyright, Designs and Patents Act 1988 or under the terms of a licence issued by the <italic>Copyright Licensing Agency Ltd, Saffron House, 6-10 Kirby Street, London, EC1N 8TS England</italic>. Applications for the copyright owner’s written permission to reproduce any part of this publication should be addressed to the publisher.</para>
    <para>Warning: The doing of an unauthorised act in relation to a copyright work may result in both a civil claim for damages and criminal prosecution.</para>
    <para>Crown copyright material is reproduced with the permission of the Controller of HMSO and the Queen’s Printer for Scotland.</para>
</story>

我的XSL看起来像这样:

<?xml version="1.0" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/Story">
        <story>
            <xsl:apply-templates/>
        </story>
    </xsl:template>

    <xsl:template match="ParagraphStyleRange">
        <xsl:apply-templates>
            <xsl:with-param name="para_style_name" select="replace(./@AppliedParagraphStyle, 'ParagraphStyle/', '')"/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="CharacterStyleRange">
        <xsl:param name="para_style_name"/>
        <xsl:variable name="char_style_name" select="replace(./@AppliedCharacterStyle, 'CharacterStyle/', '')"/>
        <xsl:for-each-group select="*" group-ending-with="Br">
            <xsl:element name="{$para_style_name}">
                <xsl:choose>
                    <xsl:when test="$char_style_name = '$ID/[No character style]'">
                        <xsl:apply-templates select="current-group()"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:element name="{$char_style_name}">
                            <xsl:apply-templates select="current-group()"/>
                        </xsl:element>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:element>
        </xsl:for-each-group>
    </xsl:template>

    <xsl:template match="Content">
        <xsl:value-of select="."/>
    </xsl:template>

    <xsl:template match="Br"/>

</xsl:stylesheet>

除了第一个paraitalic部分分开之外,哪个几乎有效。

<?xml version="1.0" encoding="UTF-8"?>
<story> 
    <para>All rights reserved. No part of this publication may be reproduced in any material form (including photocopying or storing it in any medium by electronic means and whether or not transiently or incidentally to some other use of this publication) without the written permission of the copyright owner except in accordance with the provisions of the Copyright, Designs and Patents Act 1988 or under the terms of a licence issued by the </para>
    <para><italic>Copyright Licensing Agency Ltd, Saffron House, 6-10 Kirby Street, London, EC1N 8TS England</italic></para>
    <para>. Applications for the copyright owner’s written permission to reproduce any part of this publication should be addressed to the publisher.</para>
    <para>Warning: The doing of an unauthorised act in relation to a copyright work may result in both a civil claim for damages and criminal prosecution.</para>
    <para>Crown copyright material is reproduced with the permission of the Controller of HMSO and the Queen’s Printer for Scotland.</para>
</story>

正如预期的那样,当跨越输入中的多个CharacterStyleRange元素时,我的分组方法不起作用。但是有一种分组方法,这可以工作吗?或者我最好采取不同的方法,例如在每个CharacterStyleRange终止ParagraphStyleRangeBr并重新打开它们作为简化处理的中间步骤?

1 个答案:

答案 0 :(得分:0)

所以,你几乎就在那里。将分组向上移动一级,并在匹配ParagraphStyleRange的模板中执行:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">

<xsl:output indent="yes"/>

<xsl:template match="Story">
    <story>
        <xsl:apply-templates select="ParagraphStyleRange"/>
    </story>
</xsl:template>

<xsl:template match="ParagraphStyleRange">
    <xsl:variable name="para_style_name" select="replace(@AppliedParagraphStyle, 'ParagraphStyle/', '')"/>
    <xsl:for-each-group select="CharacterStyleRange/*" group-ending-with="Br">
        <xs:element name="{para_style_name}">
            <xsl:apply-templates select="current-group()[self::Content]"/>
        </xs:element>
    </xsl:for-each-group>
</xsl:template>

<xsl:template match="Content">
    <xsl:variable name="char_style_name" select="replace(../@AppliedCharacterStyle, 'CharacterStyle/', '')"/>
    <xsl:choose>
        <xsl:when test="$char_style_name = '$ID/[No character style]'">
            <xsl:value-of select="."/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="{$char_style_name}">
                <xsl:value-of select="."/>
            </xsl:element>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>