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

XSLT转换XML为JSON:嵌入原XML并规范化格式问题

XSLT将XML嵌入JSON对象的解决方案

问题说明

我正在编写XSLT,要把输入XML转换成JSON对象,核心需求是将原XML内容作为JSON里的input属性值。目前遇到三个问题:

  • 用<xsl:copy-of select="."/>配合<xsl:output method="text"/>输出时,不仅会出现命名空间相关的输出异常,还因为XML里的双引号未转义,导致最终JSON格式无效
  • 若改用<xsl:output method="xml"/>,XML内容能正常输出,但会自动添加多余的<?xml version="1.0" encoding="UTF-8"?>声明
  • 希望去除XML内容里的缩进、换行和多余空格,用normalized-space处理输出

当前使用的XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:uswx="http://nws.weather.gov/schemas/USWX/1.0"
                xmlns:xlink="http://www.w3.org/1999/xlink"
                xmlns:metce="http://def.wmo.int/metce/2013"
                xmlns:om="http://www.opengis.net/om/2.0"
                xmlns:gml="http://www.opengis.net/gml/3.2"
                exclude-result-prefixes="uswx">
    <xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
    <xsl:template match="/">{
    "input": "<xsl:copy-of select="." />"
}
    </xsl:template>
</xsl:stylesheet>

输入XML

<?xml version="1.0" encoding="UTF-8"?>
<G-AIRMET gml:id="uuid.b3a1b430-b8e0-4943-abb7-796b9a802c49"
    xmlns="http://nws.weather.gov/schemas/USWX/1.0"
    xmlns:aixm="http://www.aixm.aero/schema/5.1.1"
    xmlns:gml="http://www.opengis.net/gml/3.2"
    xmlns:metce="http://def.wmo.int/metce/2013"
    xmlns:om="http://www.opengis.net/om/2.0"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://nws.weather.gov/schemas/USWX/1.0 http://nws.weather.gov/schemas/USWX/1.0/G-Airmet.xsd">
    <airmetStatus
        xlink:href="https://codes.nws.noaa.gov/NWSI-10-811/ProductStatus/Normal"
        xlink:title="Normal"></airmetStatus>
    <productDescription
        xlink:href="http://codes.nws.weather.gov/NWSI-10-811/AirmetProductDescription/SIERRA"
        xlink:title="SIERRA"></productDescription>
    <airmetSeries
        xlink:href="http://codes.nws.weather.gov/NWSI-10-811/AirmetSeries/S"
        xlink:title="S"></airmetSeries>
    <forecastArea>KCI</forecastArea>
</G-AIRMET>

当前输出(存在问题)

{
    "input": "<?xml version="1.0" encoding="UTF-8"?><G-AIRMET gml:id="uuid.b3a1b430-b8e0-4943-abb7-796b9a802c49" xmlns="http://nws.weather.gov/schemas/USWX/1.0" xmlns:aixm="http://www.aixm.aero/schema/5.1.1" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:metce="http://def.wmo.int/metce/2013" xmlns:om="http://www.opengis.net/om/2.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://nws.weather.gov/schemas/USWX/1.0 http://nws.weather.gov/schemas/USWX/1.0/G-Airmet.xsd"> <airmetStatus   xlink:href="https://codes.nws.noaa.gov/NWSI-10-811/ProductStatus/Normal" xlink:title="Normal"></airmetStatus> <productDescription xlink:href="http://codes.nws.weather.gov/NWSI-10-811/AirmetProductDescription/SIERRA" xlink:title="SIERRA"></productDescription> <airmetSeries xlink:href="http://codes.nws.weather.gov/NWSI-10-811/AirmetSeries/S" xlink:title="S"></airmetSeries> <forecastArea>KCI</forecastArea> </G-AIRMET>"
}

解决方案

要解决这些问题,需要同时处理XML声明去除、JSON字符串转义、空白清理三个核心点,修改后的XSLT代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:uswx="http://nws.weather.gov/schemas/USWX/1.0"
                xmlns:xlink="http://www.w3.org/1999/xlink"
                xmlns:metce="http://def.wmo.int/metce/2013"
                xmlns:om="http://www.opengis.net/om/2.0"
                xmlns:gml="http://www.opengis.net/gml/3.2"
                exclude-result-prefixes="uswx xlink metce om gml">
    <!-- 主输出为文本格式,生成合法JSON -->
    <xsl:output method="text" encoding="UTF-8" indent="no"/>
    
    <!-- 定义变量存储处理后的XML内容,内部输出省略XML声明 -->
    <xsl:variable name="xml-content">
        <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="no"/>
        <xsl:copy-of select="."/>
    </xsl:variable>
    
    <xsl:template match="/">
        {
            "input": "<xsl:call-template name="escape-quotes">
                <xsl:with-param name="text" select="normalize-space($xml-content)"/>
            </xsl:call-template>"
        }
    </xsl:template>
    
    <!-- 转义双引号的模板,确保JSON字符串合法 -->
    <xsl:template name="escape-quotes">
        <xsl:param name="text"/>
        <xsl:if test="$text != ''">
            <xsl:choose>
                <xsl:when test="contains($text, '&quot;')">
                    <xsl:value-of select="substring-before($text, '&quot;')"/>
                    <xsl:text>\"</xsl:text>
                    <xsl:call-template name="escape-quotes">
                        <xsl:with-param name="text" select="substring-after($text, '&quot;')"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$text"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

关键修改说明

  1. 去除XML声明:在存储XML内容的变量内部,单独设置<xsl:output method="xml" omit-xml-declaration="yes"/>,这样生成的XML内容不会带版本声明
  2. 清理空白:用normalize-space($xml-content)去掉XML里的所有缩进、换行和连续空格,让内容紧凑
  3. 转义双引号:通过自定义的escape-quotes模板,把XML中的双引号转义为\",避免破坏JSON的字符串结构

预期输出

{
    "input": "<G-AIRMET gml:id=\"uuid.b3a1b430-b8e0-4943-abb7-796b9a802c49\" xmlns=\"http://nws.weather.gov/schemas/USWX/1.0\" xmlns:aixm=\"http://www.aixm.aero/schema/5.1.1\" xmlns:gml=\"http://www.opengis.net/gml/3.2\" xmlns:metce=\"http://def.wmo.int/metce/2013\" xmlns:om=\"http://www.opengis.net/om/2.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://nws.weather.gov/schemas/USWX/1.0 http://nws.weather.gov/schemas/USWX/1.0/G-Airmet.xsd\"><airmetStatus xlink:href=\"https://codes.nws.noaa.gov/NWSI-10-811/ProductStatus/Normal\" xlink:title=\"Normal\"></airmetStatus><productDescription xlink:href=\"http://codes.nws.weather.gov/NWSI-10-811/AirmetProductDescription/SIERRA\" xlink:title=\"SIERRA\"></productDescription><airmetSeries xlink:href=\"http://codes.nws.weather.gov/NWSI-10-811/AirmetSeries/S\" xlink:title=\"S\"></airmetSeries><forecastArea>KCI</forecastArea></G-AIRMET>"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 13:24:52