使用XSLT将默认命名空间更改为命名空间

时间:2015-02-25 13:58:55

标签: xml namespaces xslt-1.0

我的应用程序当前生成一个使用默认命名空间的XML文件。不幸的是,接收系统需要相同名称空间的前缀。

我解决此问题的最简单方法是应用XSLT脚本。挑战是(对我而言)编写该脚本。

非常感谢任何帮助。

我的意见:

<?xml version="1.0" encoding="utf-8"?>
<xbrl xml:lang="nl" 
      xmlns="http://www.xbrl.org/2003/instance" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns:kvk-t="http://www.nltaxonomie.nl/9.0/domein/kvk/tuples/kvk-tuples" 
      xmlns:link="http://www.xbrl.org/2003/linkbase"
      xmlns:xlink="http://www.w3.org/1999/xlink" 
      xmlns:nl-cd="http://www.nltaxonomie.nl/9.0/basis/sbr/items/nl-common-data" 
      xmlns:xbrldi="http://xbrl.org/2006/xbrldi">
      <link:schemaRef xlink:type="simple" xlink:href="http://www.nltaxonomie.nl/9.0/report/kvk/entrypoints/algemeen/kvk-rpt-kleine-rechtspersoon-publicatiestukken-2014.xsd" />
      <context id="D-2014">
         <entity>
            <identifier scheme="http://www.kvk.nl/kvk-id">010101</identifier>
         </entity>
         <period>
            <startDate>2014-01-01</startDate>
            <endDate>2014-12-31</endDate>
         </period>
      </context>
      <unit id="u-EUR">
         <measure>iso4217:EUR</measure>
      </unit>
      <unit id="u-pure">
         <measure>pure</measure>
      </unit>
      <nl-cd:StatutoryNameEntity contextRef="D-2014">Company Name</nl-cd:StatutoryNameEntity>  
 </xbrl>

所需的xml如下所示:

<?xml version="1.0" encoding="utf-8"?>
<xbrli:xbrl xml:lang="nl" 

      xmlns:xbrli="http://www.xbrl.org/2003/instance"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns:kvk-t="http://www.nltaxonomie.nl/9.0/domein/kvk/tuples/kvk-tuples" 
      xmlns:link="http://www.xbrl.org/2003/linkbase"
      xmlns:xlink="http://www.w3.org/1999/xlink" 
      xmlns:nl-cd="http://www.nltaxonomie.nl/9.0/basis/sbr/items/nl-common-data" 
      xmlns:xbrldi="http://xbrl.org/2006/xbrldi">
      <link:schemaRef xlink:type="simple" xlink:href="http://www.nltaxonomie.nl/9.0/report/kvk/entrypoints/algemeen/kvk-rpt-kleine-rechtspersoon-publicatiestukken-2014.xsd" />
      <xbrli:context id="D-2014">
         <xbrli:entity>
            <xbrli:identifier scheme="http://www.kvk.nl/kvk-id">010101</xbrli:identifier>
         </xbrli:entity>
         <xbrli:period>
            <xbrli:startDate>2014-01-01</xbrli:startDate>
            <xbrli:endDate>2014-12-31</xbrli:endDate>
         </xbrli:period>
      </xbrli:context>
      <xbrli:unit id="u-EUR">
         <xbrli:measure>iso4217:EUR</xbrli:measure>
      </xbrli:unit>
      <xbrli:unit id="u-pure">
         <xbrli:measure>pure</xbrli:measure>
      </xbrli:unit>
      <nl-cd:StatutoryNameEntity contextRef="D-2014">Company Name</nl-cd:StatutoryNameEntity>  
 </xbrli:xbrl>

查看关于XML和命名空间的大量答案,我已经能够生成一个完成大部分工作的脚本。

<xsl:stylesheet version="1.0" 
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
            xmlns:xbrli="http://www.xbrl.org/2003/instance"
            xmlns:link="http://www.xbrl.org/2003/linkbase" xmlns:xlink="http://www.w3.org/1999/xlink"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            xmlns:kvk-t="http://www.nltaxonomie.nl/9.0/domein/kvk/tuples/kvk-tuples" xmlns:nl-cd="http://www.nltaxonomie.nl/9.0/basis/sbr/items/nl-common-data" 
            xmlns:rj-i="http://www.nltaxonomie.nl/9.0/basis/rj/items/rj-data" xmlns:venj-bw2-dm="http://www.nltaxonomie.nl/9.0/basis/venj/domains/venj-bw2-domains" 
            xmlns:venj-bw2-t="http://www.nltaxonomie.nl/9.0/domein/venj/tuples/venj-bw2-tuples" xmlns:rj-t="http://www.nltaxonomie.nl/9.0/domein/rj/tuples/rj-tuples" 
            xmlns:kvk-i="http://www.nltaxonomie.nl/9.0/basis/kvk/items/kvk-data" xmlns:iso4217="http://www.xbrl.org/2003/iso4217" 
            xmlns:venj-bw2-dim="http://www.nltaxonomie.nl/9.0/domein/venj/axes/venj-bw2-axes" xmlns:venj-bw2-i="http://www.nltaxonomie.nl/9.0/basis/venj/items/venj-bw2-data" 
            xmlns:xbrldi="http://xbrl.org/2006/xbrldi"  >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/">
    <xsl:apply-templates select="xbrli:xbrl"/>
</xsl:template>

<xsl:template match="xbrli:xbrl" >
    <xbrli:xbrl>
        <xsl:apply-templates select="node()|@*"/>           
    </xbrli:xbrl>
</xsl:template>

<xsl:template match="xbrli:context" >
    <xbrli:context>
        <xsl:apply-templates select="node()|@*"/>           
    </xbrli:context>
</xsl:template>

<!-- more template like this for the other elements like period, startdate, enddate -->

这个程序输出足够好:

<?xml version="1.0" encoding="utf-8"?>
    <xbrli:xbrl xml:lang="nl" xmlns:xbrli="http://www.xbrl.org/2003/instance" xmlns:link="http://www.xbrl.org/2003/linkbase" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:kvk-t="http://www.nltaxonomie.nl/9.0/domein/kvk/tuples/kvk-tuples" xmlns:nl-cd="http://www.nltaxonomie.nl/9.0/basis/sbr/items/nl-common-data" xmlns:rj-i="http://www.nltaxonomie.nl/9.0/basis/rj/items/rj-data" xmlns:venj-bw2-dm="http://www.nltaxonomie.nl/9.0/basis/venj/domains/venj-bw2-domains" xmlns:venj-bw2-t="http://www.nltaxonomie.nl/9.0/domein/venj/tuples/venj-bw2-tuples" xmlns:rj-t="http://www.nltaxonomie.nl/9.0/domein/rj/tuples/rj-tuples" xmlns:kvk-i="http://www.nltaxonomie.nl/9.0/basis/kvk/items/kvk-data" xmlns:iso4217="http://www.xbrl.org/2003/iso4217" xmlns:venj-bw2-dim="http://www.nltaxonomie.nl/9.0/domein/venj/axes/venj-bw2-axes" xmlns:venj-bw2-i="http://www.nltaxonomie.nl/9.0/basis/venj/items/venj-bw2-data" xmlns:xbrldi="http://xbrl.org/2006/xbrldi">
<link:schemaRef xlink:type="simple"
  xlink:href="http://www.nltaxonomie.nl/9.0/report/kvk/entrypoints/algemeen/kvk-rpt-kleine-rechtspersoon-publicatiestukken-2014.xsd" 
xmlns="http://www.xbrl.org/2003/instance" />
<xbrli:context id="D-2014">
  <xbrli:entity>
    <xbrli:identifier scheme="http://www.kvk.nl/kvk-id">34146188</xbrli:identifier>
</xbrli:entity>
<xbrli:period>
  <xbrli:startDate>2014-01-01</xbrli:startDate>
  <xbrli:endDate>2014-12-31</xbrli:endDate>
</xbrli:period>

    

剩下的问题是每行现在都有原始的默认命名空间:

<nl-cd:StatutoryNameEntity contextRef="D-2014" 
 xmlns="http://www.xbrl.org/2003/instance">Company name</nl-cd:StatutoryNameEntity>

有关如何正确使用这些命名空间的任何建议吗?

感谢。

1 个答案:

答案 0 :(得分:0)

问题是你的样式表是使用xsl:copy

  

实例化xsl:copy元素会创建当前节点的副本。   当前节点的命名空间节点将自动复制为   好吧,但节点的属性和子节点是   不会自动复制。

(重点补充,来源:XSL specifications

您可以使用允许指定所需前缀的xsl:copy,而不是使用xsl:element

XSLT 1.0

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xbrli="http://www.xbrl.org/2003/instance"
    xmlns:link="http://www.xbrl.org/2003/linkbase" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:kvk-t="http://www.nltaxonomie.nl/9.0/domein/kvk/tuples/kvk-tuples" 
    xmlns:nl-cd="http://www.nltaxonomie.nl/9.0/basis/sbr/items/nl-common-data" 
    xmlns:rj-i="http://www.nltaxonomie.nl/9.0/basis/rj/items/rj-data" 
    xmlns:venj-bw2-dm="http://www.nltaxonomie.nl/9.0/basis/venj/domains/venj-bw2-domains" 
    xmlns:venj-bw2-t="http://www.nltaxonomie.nl/9.0/domein/venj/tuples/venj-bw2-tuples" xmlns:rj-t="http://www.nltaxonomie.nl/9.0/domein/rj/tuples/rj-tuples" 
    xmlns:kvk-i="http://www.nltaxonomie.nl/9.0/basis/kvk/items/kvk-data" 
    xmlns:iso4217="http://www.xbrl.org/2003/iso4217" 
    xmlns:venj-bw2-dim="http://www.nltaxonomie.nl/9.0/domein/venj/axes/venj-bw2-axes" 
    xmlns:venj-bw2-i="http://www.nltaxonomie.nl/9.0/basis/venj/items/venj-bw2-data" 
    xmlns:xbrldi="http://xbrl.org/2006/xbrldi">

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

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

    <xsl:template match="@* | text()">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

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

</xsl:stylesheet>
  • http://www.xbrl.org/2003/instance命名空间中的元素明确赋予xbrli前缀,而XSLT处理器可能使用它(我使用saxon测试,它可以工作);请注意,由于xbrli前缀已经绑定到样式表中所需的命名空间,因此无需显式使用namespace属性(非常感谢michael.hor257k指出这一点)
  

XSLT处理器可以使用在中指定的QName的前缀   选择用于输出的前缀时的name属性   创建元素为XML;但是,他们不需要这样做。

(重点补充,来源:XSL specifications

  • 其他元素保留其当前前缀(和命名空间)
  • 可以使用xsl:copy
  • 复制属性和文本节点

最后一点:我觉得应用程序要求特定的前缀真的很奇怪(我不怀疑你说的是什么,我质疑应用程序的正确性); XML Namespace specifications州:

  

请注意,前缀仅用作命名空间的占位符   名称。应用程序应该使用命名空间名称,而不是前缀   构造范围超出包含文档的名称。