不使用默认命名空间的没有前缀的 XSL 输出 XML? [英] XSL output XML with no prefix without using the default namespace?

查看:21
本文介绍了不使用默认命名空间的没有前缀的 XSL 输出 XML?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 XSL,我需要按照以下方式生成输出:

I have an XSL where I need to generate output along the lines of this:

<moo xmlns="http://api.example.com">
    <foo>1358944586848</foo>
    <bar>
        <a>1</a>
        <b>2</b>
        <c>3</c>
    </bar>
</moo>

我可以这样做:

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

    <xsl:template match="/">
        <xsl:element name="moo">
            <!-- and so on -->

然而,我有点讨厌在我的 xsl 文件中使用 xsl 前缀,因为我觉得它很混乱.无论如何,使用 XPath 进行选择很容易,因为您可以根据需要将 xpath-default-namespace 设置为您正在转换的任何内容.但是就我所见,没有 element-default-namespace 可用,那么如何以一种好的方式生成所需的输出?

However, I kind of hate using the xsl prefix in my xsl files cause I feel it clutters it up a lot. Selecting with XPath is easy anyways since you can set xpath-default-namespace to whatever you're transforming from if needed. But there is no element-default-namespace available as far as I can see, so how can I generate the wanted output in a good way?

我知道我可以做到:

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

    <template match="/">
        <element name="moo" namespace="http://api.example.com">
            <!-- and so on -->

但随后我必须在我创建的每个元素上显式设置此命名空间,否则它们最终将使用 XSL 命名空间.那么有没有一种干净的方法来创建具有特定命名空间(没有前缀)的元素而不触及 xsl 文件的默认命名空间?

But then I have to set this namespace explicitly on every single element I create, or they will end up with the XSL namespace instead. So is there a clean way to create elements with a certain namespace (without a prefix) and not touching the default namespace of the xsl file?

更新:

觉得namespace-alias 可以做点什么,但是不知道怎么用.试过了,但似乎对输出没有任何影响:

Figured maybe namespace-alias could do something, but can't figure out how to use it. Tried this, but doesn't seem to make any difference in the output at all:

<stylesheet version="2.0"
    xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:out="http://api.example.com">

<namespace-alias stylesheet-prefix="out" result-prefix=""/>

    <template match="/">
        <element name="out:moo">
            <!-- and so on -->

namespace-alias 的事情可能不是我认为的那样:p

The namespace-alias thing probably isn't doing what I think it is :p

我使用的最终解决方案,基于 JLRishe 的回答

remove-prefixes.xsl

<?xml version="1.0" encoding="UTF-8"?>
<stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Transform">
    <template match="/">
        <variable name="result">
            <next-match />
        </variable>
        <apply-templates select="$result" mode="remove-prefixes" />
    </template>

    <template match="*" priority="1" mode="remove-prefixes">
        <element name="{local-name()}" namespace="{namespace-uri()}">
            <apply-templates select="@* | node()" mode="remove-prefixes" />
        </element>
    </template>
    <template match="@*|node()" mode="remove-prefixes">
        <copy>
            <apply-templates select="@* | node()" mode="remove-prefixes" />
        </copy>
    </template>

</stylesheet>

subject.xsl

<!-- snip -->
<import href="remove-prefixes.xsl" />
<!-- snip -->

推荐答案

您可以做的一件事是将 XSL 的整个结果捕获到一个变量中,然后在结尾处清除其前缀:

One thing you could do is capture the entire result of the XSL in a variable, and then blank out its prefixes at the end:

<stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Transform"
                          xmlns:p="http://api.example.com">
  <output method="xml" indent="yes"/>

  <template match="/">
    <variable name="result">
      <p:moo>
        <apply-templates />
      </p:moo>
    </variable>
    <apply-templates select="$result" mode="removePrefix" />
  </template>

  <template match="root">
    <p:something hello="hi">
      <element name="p:somethingelse" />
    </p:something>
  </template>

  <template match="p:*" mode="removePrefix">
    <element name="{local-name()}" namespace="{namespace-uri()}">
      <apply-templates select="@* | node()" mode="removePrefix" />
    </element>
  </template>

  <template match="@* | node()" mode="removePrefix">
    <copy>
      <apply-templates select="@* | node()" />
    </copy>
  </template>
</stylesheet>

在此输入上运行时:

<root>
  <top />
</root>

它产生:

<moo xmlns="http://api.example.com">
  <something hello="hi">
    <somethingelse />
  </something>
</moo>

这篇关于不使用默认命名空间的没有前缀的 XSL 输出 XML?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆