代码之家  ›  专栏  ›  技术社区  ›  Paul L

带默认命名空间但不添加前缀的XSLT转换XML?

  •  7
  • Paul L  · 技术社区  · 14 年前

    我正在尝试转换具有以下命名空间的XML文件,但在不向输出XML添加前缀的情况下,找不到使其使用默认命名空间的方法。

    原始XML文件:

    <pExport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://workflow.converga.com.au/compass">  
    

    我可以通过向默认名称空间(最后一个)添加前缀使其正常工作,但是如何在不添加前缀的情况下输出XML,在.NET 4中使用xslcompiledTransform是可能的?

    3 回复  |  直到 13 年前
        1
  •  4
  •   Dimitre Novatchev    14 年前

    我可以通过添加 默认命名空间的前缀 最后一个),但是我如何输出 不添加前缀的XML 可以使用xslcompiledTransform 在.NET 4中?

    下面是一个如何做到这一点的具体示例:

    这种转变 :

    <xsl:stylesheet version="1.0"
     xmlns="http://workflow.converga.com.au/compass"
     xmlns:c="http://workflow.converga.com.au/compass"
     xmlns:ext="http://exslt.org/common"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     exclude-result-prefixes="c ext xsl">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:param name="pnewItem">
      <item name="wine">
       <price>3</price>
       <quantity>5000</quantity>
      </item>
     </xsl:param>
    
     <xsl:template match="node()|@*" name="identity">
      <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match="c:item[last()]">
      <xsl:call-template name="identity"/>
      <xsl:copy-of select="ext:node-set($pnewItem)/*"/>
     </xsl:template>
    </xsl:stylesheet>
    

    在以下XML文档上使用xslcompiledTransform时 :

    <pExport xmlns="http://workflow.converga.com.au/compass">
     <Goods>
      <item name="tobacco">
       <price>5</price>
       <quantity>1000</quantity>
      </item>
     </Goods>
    </pExport>
    

    生成所需的(添加了新项的同一XML文档),正确的结果 :

    <pExport xmlns="http://workflow.converga.com.au/compass">
      <Goods>
        <item name="tobacco">
          <price>5</price>
          <quantity>1000</quantity>
        </item>
        <item name="wine">
          <price>3</price>
          <quantity>5000</quantity>
        </item>
      </Goods>
    </pExport>
    
        2
  •  4
  •   dolmen    14 年前

    关键是要使用 exclude-result-prefixes 属性 stylesheet 元素。

    有一些很好的解释 this section XSLT FAQ .

        3
  •  1
  •   samjudson    14 年前

    您只需要在XSLT中定义默认的名称空间。如果您还定义了一个前缀,这样您就可以轻松地从输入XML中选择项:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://workflow.converga.com.au/compass" xmlns:compass="http://workflow.converga.com.au/compass">
      <xsl:template match="compass:pExport">
        <pExport>...</pExport>
      ...
    

    上面的模板将与您的输入XML元素匹配-并且创建的literal元素将位于默认的输出命名空间(相同的命名空间)中。

    当然,您应该知道,在XML中,前缀是不相关的——如果两个项目具有相同的名称空间和本地名称,则两个项目是相同的,即使这两个前缀是为一个名称空间定义的。

    <element xmlns="http://test.com"></element>
    <ns01:element xmlns:ns01="http://test.com"></ns01:element>
    

    上面的两个元素是相同的,因为它们具有相同的完全限定名。