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

XSLT 1.0遍历XML中' RH'开头文本块无输出,求解决方案

XML文本块提取问题及解决建议

问题描述

输入XML结构如下(root节点包含一段多行文本,内含两个以 RH开头的完整块,每个块以EF开头的行结束):

<root> RH03051CDSIA280524CM1490301951171                                                                                       
 610000001                  93001                  G0305101700000000004575EUR270524C000000000000,00IT44                 
 620000001001270524270524D000000000649,3450TE                ITDA00DPN145                                                
 630000001001HAYS SRL/AVIS BUDGET ITALIA S.P.A./AR885265/2355070853/B2B/RCUR/OE5OA5200P4907R3                            
 640000001EUR270524C000000000000,00                                                                                      
 EF03051CDSIA280524CM1490301951171           0000001                              0000006                                
 RH03051CDSIA280524CM1490301951349                                                                                       
 610000001                  93001                  Z0305101699000078389249USD270524C000000001320,97IT72                 
 640000001USD270524C000000001320,97                                                                                      
 EF03051CDSIA280524CM1490301951349           0000001                              0000004                                
</root>

使用以下XSLT 1.0代码尝试提取块时无输出:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:exsl="http://exslt.org/common"
                xmlns:ns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.03"
                xmlns:BODY="urn:CBI:xsd:CBIBdyBkToCstmrStmtReq.00.01.02"
                xmlns:LMSG="urn:CBI:xsd:CBIBkToCstmrStmtReqLogMsg.00.01.02"
                xmlns:HE2E="urn:CBI:xsd:CBIHdrSrv.001.07"
                xmlns:HTRT="urn:CBI:xsd:CBIHdrTrt.001.07"
                xmlns:IDST="urn:CBI:xsd:CBIIdyStmtReqLogMsg.00.01.02"
                xmlns:DLST="urn:CBI:xsd:CBIDlyStmtReqLogMsg.00.01.02"
                xmlns:PRST="urn:CBI:xsd:CBIPrdcStmtReqLogMsg.00.01.02"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:str="http://exslt.org/strings"
                xmlns:myns="py_ns"
                extension-element-prefixes="exsl myns"
                exclude-result-prefixes="exsl ns">

    <xsl:output encoding="UTF-8" standalone="yes" indent="yes" method="xml" />

    <xsl:template match="/">
                
        <xsl:for-each select="//text[starts-with(., ' RH')]">
            <xsl:value-of select="." />
            
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

需求:用lxml库(已引入EXSLT和str扩展)提取每个 RH开头的完整文本块(从RH行到对应EF行结束)。

问题原因

  1. XPath选择器错误://text是查找名为<text>的元素,而非XML中的文本节点。正确的文本节点选择器是text(),原代码因此无法匹配到任何内容。
  2. 未收集完整块:即使找到开头的RH文本节点,原代码仅输出该节点内容,未收集后续直到EF结束的所有关联文本节点。

解决建议

修正后的XSLT代码

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:exsl="http://exslt.org/common"
                xmlns:str="http://exslt.org/strings"
                xmlns:myns="py_ns"
                extension-element-prefixes="exsl myns"
                exclude-result-prefixes="exsl">

    <xsl:output encoding="UTF-8" standalone="yes" indent="yes" method="xml" />

    <xsl:template match="/">
        <blocks>
            <!-- 匹配所有以" RH"开头的文本节点 -->
            <xsl:for-each select="/root/text()[starts-with(., ' RH')]">
                <block>
                    <!-- 输出当前RH行 -->
                    <xsl:value-of select="." />
                    <!-- 收集后续所有文本节点,直到下一个RH开头或文档结束 -->
                    <xsl:for-each select="following-sibling::text()[
                        not(starts-with(., ' RH')) 
                        and generate-id(preceding-sibling::text()[starts-with(., ' RH')][1]) = generate-id(current())
                    ]">
                        <xsl:value-of select="." />
                    </xsl:for-each>
                </block>
            </xsl:for-each>
        </blocks>
    </xsl:template>

</xsl:stylesheet>

关键修改说明

  • 修正文本节点选择:使用/root/text()[starts-with(., ' RH')]精确匹配root下以 RH开头的文本节点。
  • 完整块收集:通过following-sibling::text()遍历后续文本节点,用generate-id确保只收集当前RH块对应的后续内容(直到下一个RH出现前的所有节点)。
  • 输出结构化结果:用<blocks>和<block>标签包裹提取的内容,方便后续处理。

额外优化(可选)

如果需要将块内的多行文本合并为单行(去除多余换行和空格),可以使用EXSLT的str:replace和normalize-space:

<!-- 在block内替换换行和多余空格 -->
<xsl:variable name="raw-block">
    <xsl:value-of select="." />
    <xsl:for-each select="following-sibling::text()[
        not(starts-with(., ' RH')) 
        and generate-id(preceding-sibling::text()[starts-with(., ' RH')][1]) = generate-id(current())
    ]">
        <xsl:value-of select="." />
    </xsl:for-each>
</xsl:variable>
<xsl:value-of select="normalize-space(str:replace($raw-block, '\s+', ' '))" />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 02:30:00