【问题标题】:Copy all Attributes [Not only values of attributes but whole list of attributes] of an element复制元素的所有属性[不仅是属性的值,而且是整个属性列表]
【发布时间】:2014-08-18 07:58:37
【问题描述】:

我有一个场景,我想从输入 XML 中的 XML 标记复制所有属性,包括命名空间 [这里我的意思是整个属性列表和命名空间列表,而不仅仅是属性的值]。

例如:

输入 XML:

<?xml version="1.0" encoding="UTF-8"?>
<enricher>
    <result>
        <xbrl xmlns="http://www.xbrl.org/2003/instance" 
        xmlns:idp-com="http://www.dnb.com/IDP/Common/Vers1" 
        xmlns:idp-enumcom="http://www.dnb.com/IDP/Common/Enumeration/Common/Vers1" 
        xsi:schemaLocation="http://www.dnb.com/IDP/Product/Common/Vers1 ../Common/ProductCommonTaxonomy.xsd 
        http://www.dnb.com/IDP/Common/Vers1 ../../Data/Common/CommonTaxonomy.xsd">
            <context id="defaultI">
                <entity>
                    <identifier scheme="http://www.dnb.com">Text</identifier>
                </entity>
                <period>
                    <instant>2000-07-14</instant>
                </period>
            </context>
        </xbrl>
    </result>
</enricher>

输出 XML:

<?xml version="1.0" encoding="UTF-8"?>
<enricher>
    <result>
        <xbrlresp xmlns="http://www.xbrl.org/2003/instance" 
        xmlns:idp-com="http://www.dnb.com/IDP/Common/Vers1" 
        xmlns:idp-enumcom="http://www.dnb.com/IDP/Common/Enumeration/Common/Vers1" 
        xsi:schemaLocation="http://www.dnb.com/IDP/Product/Common/Vers1 ../Common/ProductCommonTaxonomy.xsd 
        http://www.dnb.com/IDP/Common/Vers1 ../../Data/Common/CommonTaxonomy.xsd">
            <context id="defaultI">
                <entity>
                    <identifier scheme="http://www.dnb.com">Text</identifier>
                </entity>
                <period>
                    <instant>2000-07-14</instant>
                </period>
            </context>
        </xbrlresp>
    </result>
</enricher>

输出应包含&lt;xbrlresp&gt; 标记,其中包含&lt;xbrl&gt; 的所有命名空间和属性。

【问题讨论】:

  • 嗨,为什么要更改这个 7 年前的问题的命名空间 URI?我回滚了您的编辑(并拒绝了对我的答案的更改)-因为您没有给出任何解释。

标签: xml xslt xslt-1.0


【解决方案1】:

编辑:在您揭示了实际问题之后,我还更改了样式表。同样,您的输入不是格式正确的 XML,因为没有定义命名空间:

`xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

XML 输入

<enricher>
    <result>
        <xbrl xmlns="http://www.xbrl.org/2003/instance"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:idp-com="http://www.dnb.com/IDP/Common/Vers1" 
        xmlns:idp-enumcom="http://www.dnb.com/IDP/Common/Enumeration/Common/Vers1" 
        xsi:schemaLocation="http://www.dnb.com/IDP/Product/Common/Vers1 ../Common/ProductCommonTaxonomy.xsd 
        http://www.dnb.com/IDP/Common/Vers1 ../../Data/Common/CommonTaxonomy.xsd">
            <context id="defaultI">
                <entity>
                    <identifier scheme="http://www.dnb.com">Text</identifier>
                </entity>
                <period>
                    <instant>2000-07-14</instant>
                </period>
            </context>
        </xbrl>
    </result>
</enricher>

XSLT 样式表

样式表是一个简单的身份转换,但有一个例外,即用新元素替换 xbrl 元素。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:xb="http://www.xbrl.org/2003/instance">

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

    <xsl:template match="xb:xbrl">
      <xsl:element name="xbrlresp" namespace="http://www.xbrl.org/2003/instance">
        <xsl:apply-templates select="@*|node()"/>
      </xsl:element>
    </xsl:template>

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

</xsl:transform>

XML 输出

<?xml version="1.0" encoding="UTF-8"?>
<enricher>
   <result>
      <xbrlresp xmlns="http://www.xbrl.org/2003/instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.dnb.com/IDP/Product/Common/Vers1 ../Common/ProductCommonTaxonomy.xsd          http://www.dnb.com/IDP/Common/Vers1 ../../Data/Common/CommonTaxonomy.xsd">
         <context xmlns="http://www.xbrl.org/2003/instance" xmlns:idp-com="http://www.dnb.com/IDP/Common/Vers1" xmlns:idp-enumcom="http://www.dnb.com/IDP/Common/Enumeration/Common/Vers1" id="defaultI">
            <entity>
               <identifier scheme="http://www.dnb.com">Text</identifier>
            </entity>
            <period>
               <instant>2000-07-14</instant>
            </period>
         </context>
      </xbrlresp>
   </result>
</enricher>

【讨论】:

  • @AkhilJacobJohn 嗨,也已编辑 - 这是实际答案。 All 使用我的代码时会复制命名空间。顺便说一下,命名空间不是属性。
  • @AkhilJacobJohn在 Stackoverflow 上,接受对你有帮助的答案被认为是一种礼貌。所以,请接受your last question 的回答——如果它解决了您的问题,也可以接受这个。
  • @AkhilJacobJohn 请参阅 Ian 关于如何将所有命名空间保持在一起的答案。我认为我不需要编辑我的帖子并在那里重复。
  • @AkhilJacobJohn 请避免添加更多的 cmets 来提出新问题。我们目前已经提供了充分的建议。我建议您花几分钟时间自己考虑您的问题,如果您还有其他问题,请提出一个干净、的问题。
【解决方案2】:

扩展the answer from Matthias,如果出于美学原因,您想将xbrl 元素的命名空间声明复制到您正在创建的新元素上,您可以使用

<xsl:template match="xb:xbrl">
  <xsl:element name="xbrlresp" namespace="http://www.xbrl.org/2003/instance">
    <xsl:copy-of select="namespace::*" />
    <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>

copy-of 将输入xbrl 元素中的命名空间节点复制到生成的xbrlresp,这应该会导致序列化程序添加命名空间声明。

【讨论】:

  • @AkhilJacobJohn 您是否按照 Matthias 的建议更正了输入 XML,以声明 xsi 命名空间前缀?我怀疑如果您的输入不是命名空间格式正确的,事情会变得混乱。
  • @AkhilJacobJohn 然后apply-templates 中的@* 应该捕获该属性,match="@*|node()" 身份模板将复制它。您是否有任何其他模板可能与 xsi:schemaLocation 属性节点匹配并妨碍您?
  • @AkhilJacobJohn xsi:schemaLocation 绝对是 there。既然我还在写,让我提醒你,你还没有接受上一个问题的答案!
猜你喜欢
  • 1970-01-01
  • 2014-07-23
  • 1970-01-01
  • 2010-12-15
  • 2020-10-05
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多