使用 XSLT 合并两个 xml 架构

发布于 2024-09-02 19:06:31 字数 1709 浏览 9 评论 0 原文

我正在使用 XSLT 2.0 转换 XML 架构。第一个架构 (s1.xsd) 导入第二个架构 (s2.xsd),如下所示:

s1.xsd 的内容

<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd"
    xmlns:ns1="URI1" targetNamespace="URI2" 
    elementFormDefault="qualified" attributeFormDefault="unqualified">
    <import namespace="URI1" schemaLocation="s2.xsd"/>
    <element name="element1"/>
    <element name="element2"/>
</schema>

和 s2.xsd 的内容

<schema xmlns="http://www.w3.org/2001/XMLSchema"
    xmlns:ns1="URI1" targetNamespace="URI1">
    <attribute name="attr1"/>
<schema>

我的 XSLT 声明 XS 命名空间如下:

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

我想合并 s2 的节点。 xsd 到 s1.xsd 的 元素中。到目前为止,我已经尝试过,

<xsl:template name="merge_imported_schemas">
    <xsl:for-each select="/schema/import[@namespace = //namespace::*]">
        <!-- file exists? -->
        <xsl:choose>
            <xsl:when test="boolean(document(@schemaLocation))">
                <!-- schema found -->
                <xsl:copy-of select="document(@schemaLocation)/*/node()"/>
            </xsl:when>
            <xsl:otherwise>
                <!-- schema not found -->
                <xsl:message terminate="yes">
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>

但没有得到想要的结果。谁能告诉我我做错了什么吗?我怀疑这里存在命名空间冲突,但老实说,我发现使用命名空间有点令人困惑。谢谢!

I'm transforming an XML Schema using XSLT 2.0. The first schema (s1.xsd) imports a second schema (s2.xsd) as follows:

Content of s1.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd"
    xmlns:ns1="URI1" targetNamespace="URI2" 
    elementFormDefault="qualified" attributeFormDefault="unqualified">
    <import namespace="URI1" schemaLocation="s2.xsd"/>
    <element name="element1"/>
    <element name="element2"/>
</schema>

and content of s2.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema"
    xmlns:ns1="URI1" targetNamespace="URI1">
    <attribute name="attr1"/>
<schema>

My XSLT declares the XS namespace as follows:

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

I would like to merge the nodes of s2.xsd into the <schema>-element of s1.xsd. So far, I've tried

<xsl:template name="merge_imported_schemas">
    <xsl:for-each select="/schema/import[@namespace = //namespace::*]">
        <!-- file exists? -->
        <xsl:choose>
            <xsl:when test="boolean(document(@schemaLocation))">
                <!-- schema found -->
                <xsl:copy-of select="document(@schemaLocation)/*/node()"/>
            </xsl:when>
            <xsl:otherwise>
                <!-- schema not found -->
                <xsl:message terminate="yes">
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>

but I don't get the desired result. Could anyone please tell me what I'm doing wrong? I suspect there is a namespace-collision here, but honestly I find using namespaces a little confusing. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花辞树 2024-09-09 19:06:31

您需要限定 XPath 中的元素。目前 select="/schema/import[@namespace = //namespace::*]"> 根本不匹配任何内容,因为没有元素 /schema< /代码>。 XPath 正在尝试匹配具有 no 命名空间的元素。

将其更改为 select="/xs:schema/xs:import[@namespace = //namespace::*]"> 它应该可以工作。

请记住,命名空间前缀是命名空间 URI 的别名,如果您有默认命名空间(如在 xsd 文件中),则没有前缀的元素仍然是命名空间限定的。

顺便说一句,使用 可能会取得更大成功>,并为要复制到输出树中的不同类型的节点定义不同的模板。

You need to qualify the elements in your XPath. At the moment select="/schema/import[@namespace = //namespace::*]"> doesn't match anything at all, because there is no element /schema. The XPath is trying to match elements with no namespace.

Change it to select="/xs:schema/xs:import[@namespace = //namespace::*]"> and it should work.

Remember, namespace prefixes are an alias for the namespace URI, and if you have a default namespace (as in your xsd files), elements with no prefix are still namespace-qualified.

As an aside, instead of <xsl:for-each select="/schema/import[@namespace = //namespace::*]">, you might have more success using <xsl:apply-templates select="/xs:schema/node()", and defining different templates for the different kinds of node that you wish to copy into the output tree.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文