【问题标题】:XPath 3.0 Serialize without Namespaces in Scope范围内没有命名空间的 XPath 3.0 序列化
【发布时间】:2016-02-24 20:55:24
【问题描述】:

在回答 this question 时,我突然想到我知道如何使用 XSLT 3.0 (XPath 3.0) serialize() 函数,但我不知道如何避免对范围内的命名空间进行序列化。这是一个最小的例子:

XML 输入

<?xml version="1.0" encoding="UTF-8" ?>
<ci:cichlids xmlns:ci="http://www.cichlids.com">
    <cichlid id="1">
        <name>Zeus</name>
        <color>gold</color>
        <teeth>molariform</teeth>
        <breeding-type>lekking</breeding-type>
    </cichlid>
</ci:cichlids>

XSLT 3.0 样式表

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization"
    xmlns:ci="http://www.cichlids.com">

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

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

    <xsl:template match="/ci:cichlids/cichlid">
        <xsl:variable name="serial-params">
            <output:serialization-parameters>
                <output:omit-xml-declaration value="yes"/>
            </output:serialization-parameters>
        </xsl:variable>
        <xsl:value-of select="serialize(., $serial-params/*)"/>
    </xsl:template>

</xsl:stylesheet>

实际输出

<?xml version="1.0" encoding="UTF-8"?>
<ci:cichlids xmlns:ci="http://www.cichlids.com">
    &lt;cichlid xmlns:ci="http://www.cichlids.com" id="1"&gt;
        &lt;name&gt;Zeus&lt;/name&gt;
        &lt;color&gt;gold&lt;/color&gt;
        &lt;teeth&gt;molariform&lt;/teeth&gt;
        &lt;breeding-type&gt;lekking&lt;/breeding-type&gt;
    &lt;/cichlid&gt;
</ci:cichlids>

序列化过程包括在cichlid 元素范围内的命名空间声明,尽管它没有用于此元素。我想删除这个声明并使输出看起来像

预期输出

<?xml version="1.0" encoding="UTF-8"?>
<ci:cichlids xmlns:ci="http://www.cichlids.com">
    &lt;cichlid id="1"&gt;
        &lt;name&gt;Zeus&lt;/name&gt;
        &lt;color&gt;gold&lt;/color&gt;
        &lt;teeth&gt;molariform&lt;/teeth&gt;
        &lt;breeding-type&gt;lekking&lt;/breeding-type&gt;
    &lt;/cichlid&gt;
</ci:cichlids>

我知道如何修改cichlid 元素,删除范围内的命名空间,然后序列化这个修改后的元素。但这似乎是一个相当麻烦的解决方案。我的问题是:

什么是使用 serialize() 函数序列化 XML 元素而不序列化范围内未使用的命名空间声明的规范方法?


在 Oxygen 中使用 Saxon-EE 9.6.0.7 进行测试。

【问题讨论】:

    标签: xslt serialization xslt-3.0 xpath-3.0


    【解决方案1】:

    序列化将始终为您提供您正在序列化的数据模型的忠实表示。如果要修改数据模型,这称为转换。运行转换以删除不需要的命名空间,然后序列化结果。

    【讨论】:

    • 感谢您的回答。如果我正在序列化“正常”XSLT 转换的结果,我可以使用exclude-result-prefixes 删除未使用的命名空间,而不必直接修改数据模型。使用serialize()时有没有与exclude-result-prefixes相媲美的手段?
    • @MathiasMüller,不,如果输入是已发布的,并且您的 XSLT 会执行,例如&lt;xsl:template match="/"&gt;&lt;xsl:copy-of select="//cichlid"/&gt;&lt;/xsl:template&gt;,然后使用 exclude-result-prefixes 将无助于将范围内的命名空间从输入复制到被序列化的输出。您需要确保使用&lt;xsl:copy-of select="//cichlid" copy-namespaces="no"/&gt;。如果您想使用 serialize 函数,则同样需要,您需要首先转换输入以摆脱范围内的命名空间。 exclude-result-prefixes 仅有助于 XSLT 中的命名空间。
    • @MartinHonnen 谢谢,我现在明白了。
    【解决方案2】:

    Michael Kay 已经给出了正确的答案,我接受了。这只是为了充实他的cmets。由

    运行转换以删除不需要的命名空间,然后序列化结果。

    他的意思是在调用serialize()之前应用如下转换:

    XSLT 样式表

    <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization"
        xmlns:ci="http://www.cichlids.com">
    
        <xsl:output method="xml" encoding="UTF-8" indent="yes" />
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:variable name="cichlid-without-namespace">
            <xsl:copy-of copy-namespaces="no" select="/ci:cichlids/cichlid"/>
        </xsl:variable>
    
        <xsl:template match="/ci:cichlids/cichlid">
            <xsl:variable name="serial-params">
                <output:serialization-parameters>
                    <output:omit-xml-declaration value="yes"/>
                </output:serialization-parameters>
            </xsl:variable>
            <xsl:value-of select="serialize($cichlid-without-namespace, $serial-params/*)"/>
        </xsl:template>
    
    </xsl:stylesheet>
    

    XML 输出

    <?xml version="1.0" encoding="UTF-8"?>
    <ci:cichlids xmlns:ci="http://www.cichlids.com">
        &lt;cichlid id="1"&gt;
            &lt;name&gt;Zeus&lt;/name&gt;
            &lt;color&gt;gold&lt;/color&gt;
            &lt;teeth&gt;molariform&lt;/teeth&gt;
            &lt;breeding-type&gt;lekking&lt;/breeding-type&gt;
        &lt;/cichlid&gt;
    </ci:cichlids>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多