【问题标题】:Remove XML namespaces during XSLT transformation?在 XSLT 转换期间删除 XML 名称空间?
【发布时间】:2019-11-26 19:50:11
【问题描述】:

我需要从输入的 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>

【问题讨论】:

    标签: xml xslt xslt-1.0


    【解决方案1】:

    将两个xsl:copys 替换为关联元素的非命名空间版本,并将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>
    

    根据要求。

    【讨论】:

      【解决方案2】:

      这是一个更短(20 行)且更通用的解决方案。也尽量使用 push-style:

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

      【讨论】:

        猜你喜欢
        • 2014-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-13
        • 2010-12-16
        • 2011-07-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多