如何使用 XSLT 按顺序解析嵌套标签?

发布于 2024-12-09 22:35:51 字数 1659 浏览 0 评论 0原文

我的 XML 有以下场景。

<content>
  <para>text-1 <emphasis type="bold">text-2</emphasis> text-3</para>
</content>

我想像下面一样解析它

<content>
<p>text-1 <b>text-2</b> text-3</p>
</content>

我已经创建了我的 XSLT,如下

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" encoding="ISO-8859-1" indent="no"/>

<xsl:template name="para">
    <p>
        <xsl:value-of select="text()" disable-output-escaping="yes"/>
        <xsl:for-each select="child::*">
            <xsl:if test="name()='emphasis'">
                <xsl:call-template name="emphasis"/>
            </xsl:if>
        </xsl:for-each>

    </p>
</xsl:template>
<xsl:template name="emphasis">
    <xsl:if test="attribute::type = 'bold'">
        <b>
            <xsl:value-of select="text()" disable-output-escaping="yes"/>
        </b>
    </xsl:if>
</xsl:template>

<xsl:template match="/">
    <content>
        <xsl:for-each select="content/child::*">
            <xsl:if test="name()='para'">
                <xsl:call-template name="para"/>
            </xsl:if>
        </xsl:for-each>
    </content>
</xsl:template>
</xsl:stylesheet>

所示 上面提供的 XSLT 正在生成如下所示的输出

<content>
 <p>text-1  text-3<b>text-2 </b></p>
</content>

请指导我您的建议,我怎样才能获得我想要的输出?

I have below scenario for my XML.

<content>
  <para>text-1 <emphasis type="bold">text-2</emphasis> text-3</para>
</content>

I want to parse it like below

<content>
<p>text-1 <b>text-2</b> text-3</p>
</content>

I have created my XSLT as below

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" encoding="ISO-8859-1" indent="no"/>

<xsl:template name="para">
    <p>
        <xsl:value-of select="text()" disable-output-escaping="yes"/>
        <xsl:for-each select="child::*">
            <xsl:if test="name()='emphasis'">
                <xsl:call-template name="emphasis"/>
            </xsl:if>
        </xsl:for-each>

    </p>
</xsl:template>
<xsl:template name="emphasis">
    <xsl:if test="attribute::type = 'bold'">
        <b>
            <xsl:value-of select="text()" disable-output-escaping="yes"/>
        </b>
    </xsl:if>
</xsl:template>

<xsl:template match="/">
    <content>
        <xsl:for-each select="content/child::*">
            <xsl:if test="name()='para'">
                <xsl:call-template name="para"/>
            </xsl:if>
        </xsl:for-each>
    </content>
</xsl:template>
</xsl:stylesheet>

XSLT provided above is generating output like below

<content>
 <p>text-1  text-3<b>text-2 </b></p>
</content>

Please guide me with your suggestions, how can I get my desire output?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吃兔兔 2024-12-16 22:35:51

为此,您只需使用特殊情况扩展标准身份转换,以匹配您的 paraemphasis 元素。例如,对于 para 元素,您可以将 para 替换为 p,然后继续匹配所有子节点

<xsl:template match="para">
    <p>
        <xsl:apply-templates select="@*|node()"/>
    </p>
</xsl:template>

因此,给出以下 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />

    <!-- This is the Identity Transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- Replace para with p -->
    <xsl:template match="para">
        <p>
            <xsl:apply-templates select="@*|node()"/>
        </p>
    </xsl:template>

    <!-- Replace emphasis with b -->
    <xsl:template match="emphasis[@type='bold']">
        <b>
            <xsl:apply-templates select="node()"/>
        </b>
    </xsl:template>
</xsl:stylesheet>

当应用于以下输入 XML 时,

<content> 
  <para>text-1 <emphasis type="bold">text-2</emphasis> text-3</para> 
</content> 

以下是输出

<content>
    <p>text-1 <b>text-2</b> text-3</p>
</content>

您应该能够看到,如果输入 XML 有更多标签需要转换,则扩展到其他情况是多么容易。

To do this, you just need to extend the standard Identity Transform with special cases for matching your para and emphasis elements. For example, for para elements you would the following to replace para with p and then continue matching all the child nodes

<xsl:template match="para">
    <p>
        <xsl:apply-templates select="@*|node()"/>
    </p>
</xsl:template>

So, given the following XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />

    <!-- This is the Identity Transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- Replace para with p -->
    <xsl:template match="para">
        <p>
            <xsl:apply-templates select="@*|node()"/>
        </p>
    </xsl:template>

    <!-- Replace emphasis with b -->
    <xsl:template match="emphasis[@type='bold']">
        <b>
            <xsl:apply-templates select="node()"/>
        </b>
    </xsl:template>
</xsl:stylesheet>

When applied to the following input XML

<content> 
  <para>text-1 <emphasis type="bold">text-2</emphasis> text-3</para> 
</content> 

The following is output

<content>
    <p>text-1 <b>text-2</b> text-3</p>
</content>

You should be able to see how easy it is to extend to other cases should you input XML have more tags to transform.

会发光的星星闪亮亮i 2024-12-16 22:35:51

这样做;)

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

    <xsl:template match="content">
        <content><xsl:apply-templates select="para" /></content>
    </xsl:template>

    <xsl:template match="emphasis [@type='bold']">
        <b><xsl:value-of select="." /></b>
    </xsl:template>

</xsl:stylesheet>

当你这样做时,默认模板将捕获text-1和text-3

do it like this ;)

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

    <xsl:template match="content">
        <content><xsl:apply-templates select="para" /></content>
    </xsl:template>

    <xsl:template match="emphasis [@type='bold']">
        <b><xsl:value-of select="." /></b>
    </xsl:template>

</xsl:stylesheet>

when you do it like this the default template will catch text-1 and text-3

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文