gpt4 book ai didi

xml - 使用 XSLT 合并相等的命名空间前缀

转载 作者:行者123 更新时间:2023-12-04 16:52:16 24 4
gpt4 key购买 nike

假设您有一个 XML 块,它定义了多个命名空间前缀,其中一些实际上是相同的命名空间,只是具有不同的前缀。使用 XSLT 是否有一种不太复杂的方法来合并这些前缀,以便您最终每个 namespace 只有一个前缀?例如选择最短的一个?

示例

<soapenv:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:f="http://api.example.com/Service"
xmlns:foo="http://api.example.com/Service">

<soapenv:Body>

<foo:serviceResponse>
<f:profile id="1">Alice</f:profile>
<f:profile id="2">Bob</f:profile>
</foo:serviceResponse>

</soapenv:Body>
</soapenv:Envelope>

例如应该变成这样:
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:f="http://api.example.com/Service">

<soap:Body>

<f:serviceResponse>
<f:profile id="1">Alice</f:profile>
<f:profile id="2">Bob</f:profile>
</f:serviceResponse>

</soap:Body>
</soap:Envelope>

最佳答案

你可以尝试

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:key name="namespaces" match="dec" use="@ns"/>

<xsl:variable name="prefs">
<xsl:for-each-group select="/*/namespace::*" group-by="string()">
<xsl:for-each select="current-group()">
<xsl:sort select="string-length(local-name())"/>
<xsl:if test="position() eq 1">
<dec ns="{string()}"><xsl:value-of select="local-name()"/></dec>
</xsl:if>
</xsl:for-each>
</xsl:for-each-group>
</xsl:variable>

<xsl:template match="@*">
<xsl:attribute name="{if (key('namespaces', namespace-uri(), $prefs)) then concat(key('namespaces', namespace-uri(), $prefs), ':') else ''}{local-name()}" namespace="{namespace-uri()}" select="."/>
</xsl:template>

<xsl:template match="*">
<xsl:element name="{if (key('namespaces', namespace-uri(), $prefs)) then concat(key('namespaces', namespace-uri(), $prefs), ':') else ''}{local-name()}" namespace="{namespace-uri()}">
<xsl:apply-templates select="@* , node()"/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

但这仅检查根元素上的命名空间声明(虽然它们在文档中的任何元素上都是允许的),更重要的是 XML 模式或 SOAP 消息中的属性值可以是 QName 类型(例如 xs:integer ),这样生成的文档可能不再有效(例如,您声明了两个前缀 xxs,算法消除了 xs 但属性值不是固定的说 x:integer )。因此,如果您想使用该 XSLT 来修复可能使用限定名称作为元素或属性值的 SOAP/XML 模式内容(并且不仅用于 XSLT 修复/简化的元素或属性名称),请注意。

关于xml - 使用 XSLT 合并相等的命名空间前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22227382/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com