在XSLT转换过程中删除XML名称空间?

时间:2019-07-17 22:57:46

标签: xml xslt xslt-1.0

我需要从输入XML中删除名称空间,还需要保持当前消除子节点的处理并将数据移至XSLT中的父节点。 基于各种线程,我试图通过定义另一个名称空间来删除​​名称空间,但是我无法获得所需的输出。

以下用于消除子节点和移动数据的XSLT代码有效,但是用于删除命名空间的代码无效。

XSLT代码-

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:bc="urn:com.matrix/bc"
  xmlns:test="urn:com.matrix/test"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  exclude-result-prefixes="bc test">

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

  <xsl:template match="*">
    <xsl:element name="{local-name(.)}">
      <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="@*">
    <xsl:attribute name="{local-name(.)}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="bc:PersonData">     
    <xsl:copy>
      <xsl:apply-templates select="bc:Person"/>
    </xsl:copy>
  </xsl:template>

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

</xsl:stylesheet>

输入XML-

 <?xml version="1.0" encoding="ISO-8859-1"?>
 <bc:PersonData xmlns:bc="urn:com.matrix/bc">
 <bc:Header>
    <data1>abc</data1>
    <data2>def</data2>
 </bc:Header>
 <bc:Person>
    <bc:Personal>
        <bc:FirstName>abc</bc:FirstName>
        <bc:LastName>cde</bc:LastName>
        <bc:ID>12345</bc:ID>
    </bc:Personal>
    <bc:Address>
        <bc:Address1>abc123</bc:Address1>
        <bc:Address2>def345</bc:Address2>
        <bc:Address3>uyt57</bc:Address3>
    </bc:Address>
    <bc:PhoneData>
        <bc:Phone1>111111111</bc:Phone1>
    </bc:PhoneData>
  </bc:Person>
  </bc:PersonData>

预期的输出XML-没有子节点和名称空间

 <?xml version="1.0" encoding="ISO-8859-1"?>
 <PersonData>
 <Person>
    <FirstName>abc</FirstName>
    <LastName>cde</LastName>
    <ID>12345</ID>
    <Address1>abc123</Address1>
    <Address2>def345</Address2>
    <Address3>uyt57</Address3>
    <Phone1>111111111</Phone1>
  </Person>
  </PersonData>

2 个答案:

答案 0 :(得分:1)

用关联元素的非命名版本替换两个xsl:copy,并用xs:copy-of替换xs:apply-templates,以便您的xs:template/match="*"可以按设计剥离名称空间。

然后是这个XSLT,

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:bc="urn:com.matrix/bc"
  exclude-result-prefixes="bc">

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

  <xsl:template match="*">
    <xsl:element name="{local-name(.)}">
      <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="@*">
    <xsl:attribute name="{local-name(.)}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="bc:PersonData">     
    <PersonData>
      <xsl:apply-templates select="bc:Person"/>
    </PersonData>
  </xsl:template>

  <xsl:template match="bc:Person">
    <Person>
      <xsl:apply-templates select="*/*"/>
    </Person>
  </xsl:template>

</xsl:stylesheet>

将生成此输出XML,

<?xml version="1.0" encoding="UTF-8"?>
<PersonData>
   <Person>
      <FirstName>abc</FirstName>
      <LastName>cde</LastName>
      <ID>12345</ID>
      <Address1>abc123</Address1>
      <Address2>def345</Address2>
      <Address3>uyt57</Address3>
      <Phone1>111111111</Phone1>
   </Person>
</PersonData>

根据要求。

答案 1 :(得分:1)

这是一个较短的(20行)和更通用的解决方案。另外,尽量使用推式:

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

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

  <xsl:template match="@*[namespace-uri()]">
     <xsl:attribute name="{local-name()}">
        <xsl:value-of select="."/>
     </xsl:attribute>
  </xsl:template>

  <xsl:template match="bc:Person/*"><xsl:apply-templates/></xsl:template>
  <xsl:template match="/*/*[not(self::bc:Person)]"/>
</xsl:stylesheet>

应用于提供的XML文档:

<?xml version="1.0" encoding="ISO-8859-1"?>
 <bc:PersonData xmlns:bc="urn:com.matrix/bc">
 <bc:Header>
    <data1>abc</data1>
    <data2>def</data2>
 </bc:Header>
 <bc:Person>
    <bc:Personal>
        <bc:FirstName>abc</bc:FirstName>
        <bc:LastName>cde</bc:LastName>
        <bc:ID>12345</bc:ID>
    </bc:Personal>
    <bc:Address>
        <bc:Address1>abc123</bc:Address1>
        <bc:Address2>def345</bc:Address2>
        <bc:Address3>uyt57</bc:Address3>
    </bc:Address>
    <bc:PhoneData>
        <bc:Phone1>111111111</bc:Phone1>
    </bc:PhoneData>
  </bc:Person>
  </bc:PersonData>

产生了所需的正确结果:

<PersonData>
   <Person>
      <FirstName>abc</FirstName>
      <LastName>cde</LastName>
      <ID>12345</ID>
      <Address1>abc123</Address1>
      <Address2>def345</Address2>
      <Address3>uyt57</Address3>
      <Phone1>111111111</Phone1>
   </Person>
</PersonData>