Java 如何在XML中的XSL转换中包含名称空间

Java 如何在XML中的XSL转换中包含名称空间,java,xml,xslt,namespaces,xslt-1.0,Java,Xml,Xslt,Namespaces,Xslt 1.0,我正在尝试使用JAVA将一个xml文件转换为另一个xml文件。转换后,新xml将具有一组子元素和所需的名称空间。但是,我无法包含所需的特定名称空间。不是全部就是没有。有人能帮忙吗 输入XML <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ns2:root xmlns="http://uri1.com" xmlns:ns2="http://uri2.com"> <eleme

我正在尝试使用JAVA将一个xml文件转换为另一个xml文件。转换后,新xml将具有一组子元素和所需的名称空间。但是,我无法包含所需的特定名称空间。不是全部就是没有。有人能帮忙吗

输入XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:root 
    xmlns="http://uri1.com" 
    xmlns:ns2="http://uri2.com">
    <element1>
        <elementA1>
            <elementB1>AA</elementB1>            
        </elementA1>
        <elementA2>12345</elementA2>
        <elementA3>A 000</elementA3>
     </element1>
</ns2:root>
有人能帮助我在预期的输出XML中添加特定的名称空间吗??
谢谢

在样式表标记中,将默认名称空间声明为:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://uri1.com">

只需删除根包装即可获得所需的结果:

XSLT1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/*">
    <xsl:copy-of select="*"/>
</xsl:template>

</xsl:stylesheet>


请注意,这将留下冗余的命名空间声明
xmlns:ns2=”http://uri2.com“
但这不应该是问题,除非您的目标应用程序不符合要求。

这里有一个转换,它给出了您期望的结果

在样式表中,如果需要查找特定元素,则必须重新声明输入文档中存在的名称空间。然后,您可以使用前缀引用命名空间中的元素,例如
ns1:

使用
xsl:element
构造新元素时,可以添加属性
名称空间
,这将为新元素生成默认名称空间

样式表

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:ns2="http://uri2.com">

  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="*">
    <xsl:element name="{local-name()}" namespace="http://uri1.com">
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

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

</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<element1 xmlns="http://uri1.com">
   <elementA1>
      <elementB1>AA</elementB1>
   </elementA1>
   <elementA2>12345</elementA2>
   <elementA3>A 000</elementA3>
</element1>

XML输出

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:ns2="http://uri2.com">

  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="*">
    <xsl:element name="{local-name()}" namespace="http://uri1.com">
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

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

</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<element1 xmlns="http://uri1.com">
   <elementA1>
      <elementB1>AA</elementB1>
   </elementA1>
   <elementA2>12345</elementA2>
   <elementA3>A 000</elementA3>
</element1>

AA
12345
一千

在线试用。

因此,我终于找到了一种使用默认名称空间破解结果的方法。以上所有答案都很好,这一个也适用于Java转换

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:ns1="http://uri1.com" 
    xmlns:ns2="http://uri2.com">
  <!-- For each element, create a new element with the same local-name (no namespace) -->
  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <!-- Skip the root element, just process its children. -->
  <xsl:template match="/*">
    <xsl:apply-templates/>
  </xsl:template>

  <!--override the new root element and insert the default namespace -->
  <xsl:template match="/ns2:root/ns1:element1">
        <xsl:element name="element1"
            xmlns="http://uri1.com">
            <xsl:apply-templates select="@* | node()" />
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>


我试过了,现在差不多花了一天时间;-;。希望我今天能解决这个问题:PBtw,添加名称空间没有帮助。看到它正常工作,但在Java XML转换上无法工作,我感到很难过:(…谢谢帮助:)我现在似乎得到了很多解决方案。你必须弄清楚如何让它在java上工作。你用的是哪个java处理器?用java实现的Xalan工作得很好。defaul xml函数与jdk捆绑在一起。我在我的帖子中添加了这段代码,因为格式在注释中不起作用。目标应用程序并没有抱怨,但我正在缓存这些XML值,并认为如果我可以去掉额外的名称空间会很好,但我猜没有简单的方法?我想你不需要担心它。为了删除它,您必须重建每个元素,而不是复制它,就像您已经开始做的那样,或者如Mathias Müller的回答所示。我试图通过xml构建整个xml本身:元素和标记的值。但是很少有元素是可选的,作为一个新手,我不知道如何处理这些可选标记。尝试的唯一问题是没有将新元素放入所需的命名空间中。你可以像Madeyedexter建议的那样在全球范围内这样做,也可以像Mathias Müller建议的那样明确地这样做。我将对此进行检查。这非常有效。不过,我猜在java上运行xsl时出了问题。命名空间信息将分别添加到每个元素中。我会试着看看哪里出了问题。谢谢你的帮助。
<?xml version="1.0" encoding="UTF-8"?>
<element1 xmlns="http://uri1.com">
   <elementA1>
      <elementB1>AA</elementB1>
   </elementA1>
   <elementA2>12345</elementA2>
   <elementA3>A 000</elementA3>
</element1>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:ns1="http://uri1.com" 
    xmlns:ns2="http://uri2.com">
  <!-- For each element, create a new element with the same local-name (no namespace) -->
  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <!-- Skip the root element, just process its children. -->
  <xsl:template match="/*">
    <xsl:apply-templates/>
  </xsl:template>

  <!--override the new root element and insert the default namespace -->
  <xsl:template match="/ns2:root/ns1:element1">
        <xsl:element name="element1"
            xmlns="http://uri1.com">
            <xsl:apply-templates select="@* | node()" />
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>