如何使用XSL删除命名空间并仅保留原始XML文档中的一些元素?

时间:2011-09-29 05:16:21

标签: xml xslt xml-namespaces

下面是我的XML。我想用XSL解析它。我想要实现的是删除命名空间(xmlns)然后只保留一些元素及其属性。我找到了一种删除命名空间的方法,但是当我将它与代码放在一起以保留一些元素时,它不起作用。我已经尝试了身份,但仍然无法正常工作。

我希望有人可以分享一些东西。非常感谢你提前。

XML输入:

<Transaction xmlns="http://www.test.com/rdc.xsd">
    <Transaction>
       <StoreName id="aa">STORE A</StoreName>
       <TransNo>TXN0001</TransNo>
       <RegisterNo>REG001</RegisterNo>
       <Items>
          <Item id="1">
             <ItemID>A001</ItemID>
             <ItemDesc>Keychain</ItemDesc>
          </Item>
          <Item id="2">
             <ItemID>A002</ItemID>
             <ItemDesc>Wallet</ItemDesc>
          </Item>
       </Items>
       <IDONTLIKETHIS_1>
          <STOREXXX>XXX-</STOREXXX>
          <TRANSXXX>YYY</TRANSXXX>
       </IDONTLIKETHIS_1>
       <IDONTLIKETHIS_2>
          <STOREXXX>XXX-</STOREXXX>
          <TRANSXXX>YYY</TRANSXXX>
       </IDONTLIKETHIS_2>
    </Transaction>
<Transaction>

预期的XML输出:

<Transaction>
    <Transaction>
       <StoreName id="aa">STORE A</StoreName>
       <TransNo>TXN0001</TransNo>
       <RegisterNo>REG001</RegisterNo>
       <Items>
          <Item id="1">
             <ItemID>A001</ItemID>
             <ItemDesc>Keychain</ItemDesc>
          </Item>
          <Item id="2">
             <ItemID>A002</ItemID>
             <ItemDesc>Wallet</ItemDesc>
          </Item>
       </Items>
    </Transaction>
<Transaction>

用于删除命名空间的代码(xmlns):

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

1 个答案:

答案 0 :(得分:1)

<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:x="http://invia.fujitsu.com/RetailDATACenter/rdc.xsd">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>

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

     <xsl:template match="node()[not(self::*)]">
      <xsl:copy-of select="."/>
     </xsl:template>

     <xsl:template match="x:IDONTLIKETHIS_1 | x:IDONTLIKETHIS_2"/>
</xsl:stylesheet>

<强>解释

  1. 匹配“*”的模板匹配任何元素并使用相同名称重新创建<xsl:element>),但不复制任何命名空间节点。它还复制了此元素的所有属性。然后它在所有这个元素的子节点上应用模板(包括它自己 - 递归) - 不仅是元素,还包括所有类型的子节点:元素,文本节点,处理指令和注释。

  2. 最后一个模板匹配我们不想复制到输出的任何节点,并使用空模板主体完成此操作(不复制)。

  3. 第二个模板匹配并复制所有非元素的节点,不包括文档节点/