0

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

源 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>

有什么好主意吗?

4

1 回答 1

2

这是一种方法。

当这个 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规范中的命名空间中的一部分开始:

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

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

简而言之,这意味着当在元素上声明命名空间时,它实际上被定义为用于该原始范围内的所有元素。此外,如果在元素上使用命名空间而不首先在其他地方定义,则在该元素上发生适当的定义。

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

  1. 第一个模板 -身份模板- 将所有节点和属性按原样从源 XML 复制到结果 XML。
  2. 第二个模板将原始<Accounts>元素替换为新元素;顺便说一下,这个新<Accounts>元素没有定义http:example.com/test1命名空间。最后,此模板将模板应用于<Accounts>.
  3. 当处理器到达<test:Siblings>时,它会看到一个名称空间,尽管该名称空间存在于原始 XML 中,但尚未在结果文档中正确定义。因此,此定义被添加到<test:Siblings>.
于 2013-05-03T20:24:40.917 回答