XSL模板匹配模式适用于所有子节点



这是我的样式表的一个片段:

	<xsl:template name="root" match="/">
		<xsl:apply-templates select="/office:document-content/office:body/office:text"/>
	</xsl:template>
	<!-- -->
	<xsl:template name="text" match="office:text">
		<text>
			<xsl:apply-templates/>
		</text>
	</xsl:template>
	<xsl:template match="text:h|text:p">
		<para>
			<xsl:value-of select="1"/>
		</para>
	</xsl:template>

这就是输入xml文件。代码段:

<office:body>
    <office:text text:use-soft-page-breaks="true">
        <text:h text:style-name="P1" text:outline-level="1"><text:bookmark-start text:name="_Toc433035627"/>Права за<text:s/>достъп<text:s/>до ARISTA MDM<text:bookmark-end text:name="_Toc433035627"/></text:h>
        <text:p text:style-name="Normal">Входът в системата се осъществява с потребителско име и парола, като проверката на потребителското име и паролата се извършва в управляващия център ARISTA<text:s/>MDM или чрез активна директория (MS AD). При създаване на нов потребител има възможност да се определи дали вписването да се извършва от активната директория (MS AD) или управляващия център ARISTA MDM.</text:p>
        <text:p text:style-name="Header">Правата<text:s/>на потребителя конфигурират неговия достъп до:</text:p>
        <text:list text:style-name="LFO4" text:continue-numbering="true">
            <text:list-item>
                <text:p text:style-name="ListBullet2">Менюта и полета;</text:p>
            </text:list-item>
            <text:list-item>
                <text:p text:style-name="ListBullet2">Параметри на устройства;</text:p>
            </text:list-item>
            <text:list-item>
                <text:p text:style-name="ListBullet2">Части на структурата (папки, подпапки).<text:s/></text:p>
            </text:list-item>
        </text:list>
        <text:list text:style-name="LFO9" text:continue-numbering="true">
            <text:list-item>
                <text:p text:style-name="ListNumber2">Потребителите наследяват правата на ролите, които притежават. Единственият начин потребителите да получават или да им се отнемат права е чрез добавяне или премахване на<text:s/>ролите;</text:p>
            </text:list-item>
            <text:list-item>
                <text:p text:style-name="ListNumber2">Паролите на потребителите, които се валидират към центъра<text:s/>ARISTA<text:s/>MDM<text:s/>могат да имат период на валидност. Периода на валидност се задава при създаване на потребителя;</text:p>
            </text:list-item>
            <text:list-item>
                <text:p text:style-name="ListNumber2">При изтичане на периода на валидност на паролата, от потребителя се изисква да промени паролата си;</text:p>
            </text:list-item>
            <text:list-item>
                <text:p text:style-name="ListNumber2">Всички действия на потребителите ще бъдат записвани и показвани в табличен вид, като информацията включва: потребителско име, действие, дата и час, модул и допълнителна информация;</text:p>
            </text:list-item>
            <text:list-item>
                <text:p text:style-name="ListNumber2">Записването на потребителските действия се активира или деактивира при създаване на нов потребител или промяна на данните на съществуващ.</text:p>
            </text:list-item>
        </text:list>
        <text:h text:style-name="Heading1" text:outline-level="1"><text:bookmark-start text:name="_Toc414357454"/><text:bookmark-start text:name="_Toc433035628"/>Вписване в ARISTA MDM<text:bookmark-end text:name="_Toc414357454"/><text:bookmark-end text:name="_Toc433035628"/></text:h>
        <text:p text:style-name="Normal">
            <text:span text:style-name="Strong">След въвеждане на адреса на системата се появява прозореца за вписване на потребители.</text:span>
        </text:p>
        <text:p text:style-name="Quote">За вписване в системата, операторът трябва да въведе съответното<text:s/>потребителско име и парола и да натисне бутон.</text:p>
    </office:text>
</office:body>

这是我得到的输出:

<text>
	<para>1</para>
	<para>1</para>
	<para>1</para>
	<para>1</para>
	<para>1</para>
	<para>1</para>
	<para>1</para>
	<para>1</para>
	<para>1</para>
	<para>1</para>
	<para>1</para>
	<para>1</para>
	<para>1</para>
	<para>1</para>
</text>

请告诉我为什么<xsl:template match="text:h|text:p">也应用于其他同级(text:list)元素?我已被明确告知仅应用于text:htext:p。对不起,我英语不好。谢谢你抽出时间。

有两件事可以一起解释您所看到的行为。

  • 首先,要意识到,只要select属性缺失,<xsl:apply-templates />就会应用于当前节点的所有子级,因此您将模板应用于匹配的office:text元素(包括那些text:list元素)的所有元素子级。

  • 其次,虽然没有与text:list元素匹配的模板,但XSLT包含内置模板,这些模板旨在允许递归处理在没有成功的模式匹配时继续进行,并且确实匹配这些元素。这样做的内置模板看起来像这样:

    <xsl:template match="*|/">
        <xsl:apply-templates/>
    </xsl:template>
    

因此,内置模板匹配text:list子级(因为它匹配所有元素),然后将模板应用于子级,这将导致显式模板的进一步匹配。

请告诉我为什么申请<xsl:template match="text:h|text:p">其他同级(text:list)元素也是?

你凭什么认为是这样的?如果您更改:

<xsl:template match="text:h|text:p">
    <para>
        <xsl:value-of select="1"/>
    </para>
</xsl:template>

至:

<xsl:template match="text:h|text:p">
    <para>
        <xsl:value-of select="name()"/>
    </para>
</xsl:template>

你会得到一个结果:

<text>
   <para>text:h</para>
   <para>text:p</para>
   <para>text:p</para>
   <para>text:p</para>
   <para>text:p</para>
   <para>text:p</para>
   <para>text:p</para>
   <para>text:p</para>
   <para>text:p</para>
   <para>text:p</para>
   <para>text:p</para>
   <para>text:h</para>
   <para>text:p</para>
   <para>text:p</para>
</text>

所以很明显CCD_ 12元素是而不是处理的。

最新更新