身份模板和优先级在 XSL 中创建重复节点 [英] Identity template and priority creating duplicate nodes in XSL

查看:35
本文介绍了身份模板和优先级在 XSL 中创建重复节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有以下 XML 输入:

So I have the following XML input:

<parent>
  <para> text 1 <NodeTypeA id="1">element1</NodeTypeA> text2 <Xref ref="1"/> text3</para>
  <para>text 4</para>
  <para><NodeTypeA id="2">elt2</NodeTypeA></para>
  <para>text5 <Xref red="2"/>text6 <Xref ref="3"/>text7</para>
</parent>

我正在尝试提取外部参照节点并将平行节点一分为二,感谢 这个答案,这是有效的.但是,在我的 XSL 代码中,我需要一个身份模板,并在我的模板中设置一些优先级.

I'm trying to extract the Xref node and split the para nodes in two, and thanks to this answer, this works. However, in my XSL code, I need to have a identity template, and some priority in my templates.

这是我的完整代码:

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

    <xsl:template match="@*|node()" priority="0">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="para[Xref]" priority="1">
        <xsl:apply-templates select="node()[1]"/>
    </xsl:template>

    <xsl:template match="para/node()[not(self::Xref)]" priority="1">
        <xsl:param name="group" select="."/>
        <xsl:apply-templates select="following-sibling::node()[1]">
            <xsl:with-param name="group" select="$group | ."/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="para/node()[not(self::Xref) and not(following-sibling::Xref)][last()]" priority="1">
        <xsl:param name="group" select="."/>
        <para>
            <xsl:copy-of select="$group | ."/>
        </para>
    </xsl:template>

    <xsl:template match="para/Xref" priority="1">
        <xsl:param name="group"/>
        <xsl:if test="$group">
            <para>
                <xsl:copy-of select="$group"/>
            </para>
        </xsl:if>
        <xsl:copy-of select="."/>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>

</xsl:stylesheet>

问题是不包含外部参照节点的平行节点在我的输出中加倍,而包含外部参照节点的平行节点转换得很好.这是我得到的 XML 输出:

The problem is that the para nodes that do NOT contain a Xref node are doubled in my output while those containing an Xref node are transformed just fine. Here's the XML output I get:

<?xml version="1.0"?>
<parent>
    <para> text 1 <NodeTypeA id="1">element1</NodeTypeA> text2 </para>
    <Xref ref="1" />
    <para> text3</para>
    <para><para>text 4</para></para>
    <para><para><NodeTypeA id="2">elt2</NodeTypeA></para></para>
    <para>text5 </para>
    <Xref red="2" />
    <para>text6 </para>
    <Xref ref="3" />
    <para>text7</para>
</parent>

为什么添加身份模板和一些优先级会破坏这一点,我该如何解决?

Why does adding an identity template and some priority break this, and how can i fix it ?

PS:我使用的是 XSLT 1

PS: I'm using XSLT 1

推荐答案

如果我已经正确理解了问题——描述相当混乱,

In case I have understood correctly the problem -- the description is rather confusing,

这是一种解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kPrecedingXref" match="node()[not(self::Xref)]" 
                                use="generate-id(following-sibling::Xref[1])"/>

  <xsl:template match="node()|@*" name="identity">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="para[Xref]">
    <xsl:apply-templates select="Xref"/>
    <para>
      <xsl:apply-templates 
                    select="node()[not(self::Xref) and not(following-sibling::Xref)]"/>
    </para>
  </xsl:template>

  <xsl:template match="para/Xref">
    <para>
      <xsl:apply-templates select="key('kPrecedingXref', generate-id())"/>
    </para>
    <xsl:call-template name="identity"/>
  </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<parent>
  <para> text 1 <NodeTypeA id="1">element1</NodeTypeA> text2 <Xref ref="1"/> text3</para>
  <para>text 4</para>
  <para><NodeTypeA id="2">elt2</NodeTypeA></para>
  <para>text5 <Xref red="2"/>text6 <Xref ref="3"/>text7</para>
</parent>

产生了想要的、正确的结果:

<parent>
   <para> text 1 <NodeTypeA id="1">element1</NodeTypeA> text2 </para>
   <Xref ref="1"/>
   <para> text3</para>
   <para>text 4</para>
   <para>
      <NodeTypeA id="2">elt2</NodeTypeA>
   </para>
   <para>text5 </para>
   <Xref red="2"/>
   <para>text6 </para>
   <Xref ref="3"/>
   <para>text7</para>
</parent>

这篇关于身份模板和优先级在 XSL 中创建重复节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆