namespace error: namespace prefix bd on关键字没有定义



我有一个巨大的xml文件,我想分割成单独的xml文档;每个单独的xml文件都应该有一个显式的名称空间声明,如下面的"期望输出"部分所示。然而,我一直得到错误"命名空间错误:命名空间前缀bd上的关键字是没有定义"

我的问题是,我如何显式地告诉我的XSLT处理器在结果输出中放置名称空间声明的位置?我在网上看了几个教程,但我不太明白如何解决这个问题。

部分XSLT代码段

...
...
<xsl:template match="chapter">
  <bd:chapter>
    <xsl:apply-templates select="name" />
    <xsl:apply-templates select="page" />
  </bd:chapter>
</xsl:template>
<xsl:template match="name">
  <bd:name>
    <xsl:value-of select="." />
  </bd:name>
</xsl:template>
...
...
所需输出

<?xml version="1.0" encoding="utf-8" ?>
<books>
<bd:book xmlns:bd="http://www.bd.org.za/db" xmlns:cd="http://www.bd.org.za/cd">
    <bd:name>book01</bd:name>
    <bd:chapter>
      <cd:name>chapter01<cd:name>
      <bd:page>
    <cd:title></cd:title>
    <pd:description></pd:description>
      </bd:page>
    </bd:chapter>
</bd:book>
...
...
...
</books>

Update # 1

<?xml version="1.0" encoding="utf-8" ?>
<books>
<book>
    <name>book01</name>
    <chapter>
      <name>chapter01<name>
      <page>
    <title></title>
    <description></description>
      </page>
    </chapter>
</book>
...
...
...
</books>

更新# 2

@polishchuk Update2给出以下结果

<?xml version="1.0"?>
<root xmlns:pd="namespace2">
  <pd:Book xmlns:pd="http://namespace1.org/">
    <pd_1:Name xmlns:pd="namespace2" xmlns:pd_1="http://namespace1.org/">A</pd_1:Name>
    <pd:Description xmlns:pd="namespace2">A1</pd:Description>
  </pd:Book>
  <pd:Book xmlns:pd="http://namespace1.org/">
    <pd_1:Name xmlns:pd="namespace2" xmlns:pd_1="http://namespace1.org/">B</pd_1:Name>
    <pd:Description xmlns:pd="namespace2">B1</pd:Description>
  </pd:Book>
</root>

我只希望名称空间出现在book节点内。请参见

<?xml version="1.0"?>
<root>
  <pd:Book xmlns:pd="http://namespace1.org/">
    <pd:Name >A</pd:Name>
    <pd:Description>A1</pd:Description>
  </pd:Book>
  <pd:Book xmlns:pd="http://namespace1.org/">
    <pd:Name>B</pd_1:Name>
    <pd:Description>B1</pd:Description>
  </pd:Book>
</root>

假设您有以下XML:

<root>
  <book>
    <name>A</name>
    <description>A1</description>
  </book>
  <book>
    <name>B</name>
    <description>B1</description>
  </book>
</root>

期望的XML(带名称空间):

<root xmlns:bd="namespace1" xmlns:pd="namespace2">
  <bd:Book>
    <bd:Name>A</bd:Name>
    <pd:Description>A1</pd:Description>
  </bd:Book>
  <bd:Book>
    <bd:Name>B</bd:Name>
    <pd:Description>B1</pd:Description>
  </bd:Book>
</root>

适当XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:bd="namespace1"
                xmlns:pd="namespace2"
                >
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <root>
      <xsl:apply-templates/>
    </root>
  </xsl:template>
  <xsl:template match="book">
    <bd:Book>
      <xsl:apply-templates />
    </bd:Book>
  </xsl:template>
  <xsl:template match="name">
    <bd:Name>
      <xsl:value-of select="."/>
    </bd:Name>
  </xsl:template>
  <xsl:template match="description">
    <pd:Description>
      <xsl:value-of select="."/>
    </pd:Description>
  </xsl:template>
</xsl:stylesheet>

您只需在XSLT中添加名称空间,然后使用名称空间的前缀创建节点。更新1:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:pd="namespace2"
                >
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <root>
      <xsl:apply-templates/>
    </root>
  </xsl:template>
  <xsl:template match="book">
    <bd:Book xmlns:bd="namespace1">
      <xsl:apply-templates />
    </bd:Book>
  </xsl:template>
  <xsl:template match="name">
    <bd:Name xmlns:bd="namespace1">
      <xsl:value-of select="."/>
    </bd:Name>
  </xsl:template>
  <xsl:template match="description">
    <pd:Description>
      <xsl:value-of select="."/>
    </pd:Description>
  </xsl:template>
</xsl:stylesheet>

更新2 :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:pd="namespace2"
                >
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <root>
      <xsl:apply-templates/>
    </root>
  </xsl:template>
  <xsl:template match="book">
    <Book xmlns="namespace1">
      <xsl:apply-templates />
    </Book>
  </xsl:template>
  <xsl:template match="name">
    <Name xmlns="namespace1">
      <xsl:value-of select="."/>
    </Name>
  </xsl:template>
  <xsl:template match="description">
    <pd:Description>
      <xsl:value-of select="."/>
    </pd:Description>
  </xsl:template>
</xsl:stylesheet>

更新3 :这个XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <root>
      <xsl:apply-templates/>
    </root>
  </xsl:template>
  <xsl:template match="book">
    <pd:Book xmlns:pd="namespace2">
      <xsl:apply-templates />
    </pd:Book>
  </xsl:template>
  <xsl:template match="name">
    <pd:Name  xmlns:pd="namespace2">
      <xsl:value-of select="."/>
    </pd:Name>
  </xsl:template>
  <xsl:template match="description">
    <pd:Description  xmlns:pd="namespace2">
      <xsl:value-of select="."/>
    </pd:Description>
  </xsl:template>
</xsl:stylesheet>

输出XML(就像在你的更新2,我使用MSXML 6.0),但对于XML引擎,无论在哪里定义命名空间:

<root>
  <pd:Book xmlns:pd="namespace2">
    <pd:Name>A</pd:Name>
    <pd:Description>A1</pd:Description>
  </pd:Book>
  <pd:Book xmlns:pd="namespace2">
    <pd:Name>B</pd:Name>
    <pd:Description>B1</pd:Description>
  </pd:Book>
</root>