XSLT 1.0 将命名空间移动到子节点 [英] XSLT 1.0 to move namespace to child node

查看:48
本文介绍了XSLT 1.0 将命名空间移动到子节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只能访问 xpath 1.0 命令和函数.我需要将命名空间声明从根节点移动到开始使用该命名空间的子节点.

I only have access to xpath 1.0 commands and functions. I need to move the namespace declaration from the root node to a child node where that namespace starts to be used.

源 XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Accounts xmlns:test="http:example.com/test1">
    <ParentAccount>10113146</ParentAccount>
    <test1>test1</test1>
    <test2>test2</test2>
    <test:Siblings>
        <test:CustomerNumber>10113146</test:CustomerNumber>
        <test:CustomerNumber>120051520</test:CustomerNumber>
    </test:Siblings>
</Accounts>

所需的 XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Accounts x>
    <ParentAccount>10113146</ParentAccount>
    <test1>test1</test1>
    <test2>test2</test2>
    <test:Siblings xmlns:test="http:example.com/test1">
        <test:CustomerNumber>10113146</test:CustomerNumber>
        <test:CustomerNumber>120051520</test:CustomerNumber>
    </test:Siblings>
</Accounts>

有什么好点子吗?

推荐答案

这是一种方法.

当这个 XSLT:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output omit-xml-declaration="no" indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="Accounts">
     <Accounts>
       <xsl:apply-templates />
     </Accounts>
  </xsl:template>

</xsl:stylesheet>

...应用于提供的 XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Accounts xmlns:test="http:example.com/test1">
  <ParentAccount>10113146</ParentAccount>
  <test1>test1</test1>
  <test2>test2</test2>
  <test:Siblings>
    <test:CustomerNumber>10113146</test:CustomerNumber>
    <test:CustomerNumber>120051520</test:CustomerNumber>
  </test:Siblings>
</Accounts>

...产生了想要的结果:

<?xml version="1.0"?>
<Accounts>
  <ParentAccount>10113146</ParentAccount>
  <test1>test1</test1>
  <test2>test2</test2>
  <test:Siblings xmlns:test="http:example.com/test1">
    <test:CustomerNumber>10113146</test:CustomerNumber>
    <test:CustomerNumber>120051520</test:CustomerNumber>
  </test:Siblings>
</Accounts>

说明:

为什么这有效的解释从 XML 中的命名空间的一节开始1.0 规范:

The explanation behind why this works starts with a section from the Namespaces in XML 1.0 spec:

声明前缀的命名空间声明的范围从开始标记的开头,它出现在对应的结束标签,不包括任何内部声明的范围具有相同的 NSAttName 部分.在空标签的情况下,范围是标签本身.

The scope of a namespace declaration declaring a prefix extends from the beginning of the start-tag in which it appears to the end of the corresponding end-tag, excluding the scope of any inner declarations with the same NSAttName part. In the case of an empty tag, the scope is the tag itself.

这样的命名空间声明适用于所有元素和属性其范围内的名称,其前缀与指定的前缀匹配声明.

Such a namespace declaration applies to all element and attribute names within its scope whose prefix matches that specified in the declaration.

简而言之,这意味着当在元素上声明命名空间时,它实际上被定义为用于原始作用域下的所有元素.此外,如果在元素上使用命名空间而没有先在别处定义,则相应的定义会出现在该元素上.

In a nutshell, this means that when a namespace is declared on an element, it is, in effect, defined for use on all elements underneath that original scope. Additionally, should a namespace be used on an element without first being defined elsewhere, the appropriate definition occurs on that element.

因此,使用您的文档和我的 XSLT,让我们看看效果如何:

So, using your document and my XSLT, let's see how this plays out:

  1. 第一个模板 - 身份模板 - 复制所有节点并从源 XML 到结果 XML 的原样属性.
  2. 第二个模板用一个新的替换了原来的 元素;顺便提一下,这个新的 元素没有定义 http:example.com/test1 命名空间. 最后,这个模板将模板应用于 的所有子元素.
  3. 当处理器到达 时,它会看到一个命名空间,尽管该命名空间存在于原始 XML 中,但并未在结果文档中正确定义.因此,此定义被添加到 .
  1. The first template - The Identity Template - copies all nodes and attributes as-is from the source XML to the result XML.
  2. The second template replaces the original <Accounts> element with a new one; incidentally, this new <Accounts> element does not define the http:example.com/test1 namespace. Finally, this template applies templates to all child elements of <Accounts>.
  3. When the processor reaches <test:Siblings>, it sees a namespace that, although present in the original XML, has not been properly defined in the result document. As such, this definition is added to <test:Siblings>.

这篇关于XSLT 1.0 将命名空间移动到子节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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