You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSLT排序时<xsl:value-of>丢失blockquote标签,Oxygen中如何保留?

问题:XML排序时保留<blockquote>标签

我有如下结构的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <card>
        <k>аванс</k>
        <body>
            <blockquote>аванс.</blockquote>
        </body>
    </card>
    <card>
        <k>авансыла-</k>
        <body>
            <blockquote>авансировать;</blockquote>
            <blockquote>авансылап авансом.</blockquote>
        </body>
    </card>
    <card>
        <k>авансылоо</k>
        <body>
            <blockquote>и. д. от авансыла-</blockquote>
            <blockquote>авансирование.</blockquote>
        </body>
    </card>
</root>

我尝试用以下XSLT按<k>元素的值对<card>排序:

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

<xsl:template match="/">
<root>
  <xsl:for-each select="root/card">
    <xsl:sort select="upper-case(k)" lang="ru"/>
      <k><xsl:value-of select="k"/></k>
      <body><xsl:value-of select="body"/></body>
  </xsl:for-each>
</root>
</xsl:template>

</xsl:stylesheet>

在线编辑器输出符合预期,但用Oxygen XML Editor处理大文件时,所有<blockquote>标签都被移除了,请问如何在最终XML中保留这些标签?


解决方案

问题出在xsl:value-of的使用上:这个指令只会提取节点的文本内容,不会保留子元素(比如<blockquote>)。要完整保留节点结构,需要替换为xsl:copy-of,它会复制整个节点树(包括子元素和属性)。

方案一:直接替换指令

修改后的XSLT如下:

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

<xsl:template match="/">
<root>
  <xsl:for-each select="root/card">
    <xsl:sort select="upper-case(k)" lang="ru"/>
    <!-- 复制完整的<k>和<body>节点,包括子元素 -->
    <xsl:copy-of select="k"/>
    <xsl:copy-of select="body"/>
  </xsl:for-each>
</root>
</xsl:template>

</xsl:stylesheet>

方案二:模板匹配(更适合大文件)

如果需要更灵活的后续修改,也可以用模板匹配结合排序,符合XSLT最佳实践:

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

<!-- 匹配根节点,输出排序后的card列表 -->
<xsl:template match="/root">
  <root>
    <xsl:apply-templates select="card">
      <xsl:sort select="upper-case(k)" lang="ru"/>
    </xsl:apply-templates>
  </root>
</xsl:template>

<!-- 默认模板:复制所有节点和属性,保留原结构 -->
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

第二种方式利用XSLT默认模板机制,自动复制所有未被自定义模板匹配的节点,既能完成排序,又完整保留原XML的所有结构(包括<blockquote>标签)。


内容的提问来源于stack exchange,提问作者xinatanil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 03:35:21