【问题标题】:remove unwanted namespaces from child node从子节点中删除不需要的命名空间
【发布时间】:2022-08-18 05:30:50
【问题描述】:

大家好,这是输入 XML,我想要所有的,因为它是 ns0:operationbody 元素内的 XML 结构。其中打开 < 应该是实体形式, > 应该是 \'>\' 符号。

主要问题是正在复制一些不在输入 XML 子元素中的额外命名空间

    <?xml version = \'1.0\' encoding = \'UTF-8\'?>
    <root xmlns=\"GlobalInteraction.xsdobjects\">
       <ns1:Account xmlns:ns1=\"GlobalInteraction.xsdobjects\">
          <ns1:ExtReference>
             <commonProvide:ExternalSystem xmlns:commonProvide=\"commonentities.xsdobjects.extload\">BFG</commonProvide:ExternalSystem>
             <commonProvide:ServiceElement2 xmlns:commonProvide=\"commonentities.xsdobjects.extload\">
<!-- At this point no namespace is given but in output namespaces are displaying -->
                **<commonProvide:ElementNumber>30</commonProvide:ElementNumber>
                <commonProvide:PartNumber>60000283</commonProvide:PartNumber>**
             </commonProvide:ServiceElement2>
          </ns1:ExtReference>
          <ns1:CustomerLegalName xmlns:ns1=\"GlobalInteraction.xsdobjects\">CLARINS</ns1:CustomerLegalName>
          <ns1:Type>Global</ns1:Type>
          <ns1:SubType>National</ns1:SubType>
       </ns1:Account>
    </root>

运行代码后,输出如下:

<ns0:OperationBody xmlns:ns0=\"serviceBusiness.xsdobjects.extload.services.classic.bt\">&lt;root xmlns=\"GlobalInteraction.xsdobjects.extload\">
   &lt;ns1:Account xmlns:ns1=\"GlobalInteraction.xsdobjects.extload\">
      &lt;ns1:ExtReference xmlns:ns1=\"GlobalInteraction.xsdobjects.extload\">
         &lt;commonProvide:ExternalSystem xmlns:commonProvide=\"commonentities.xsdobjects.extload\" xmlns:ns1=\"GlobalInteraction.xsdobjects.extload\">BFG&lt;/commonProvide:ExternalSystem>
      &lt;/ns1:ExtReference>
      &lt;ns1:ExtReference xmlns:ns1=\"GlobalInteraction.xsdobjects.extload\">
         &lt;commonProvide:ExternalSystem xmlns:commonProvide=\"commonentities.xsdobjects.extload\" xmlns:ns1=\"GlobalInteraction.xsdobjects.extload\">BFG&lt;/commonProvide:ExternalSystem>
         &lt;commonProvide:ServiceElement2 xmlns:commonProvide=\"commonentities.xsdobjects.extload\" xmlns:ns1=\"GlobalInteraction.xsdobjects.extload\">
            &lt;commonProvide:ElementNumber xmlns:commonProvide=\"commonentities.xsdobjects.extload\" xmlns:ns1=\"GlobalInteraction.xsdobjects.extload\">30&lt;/commonProvide:ElementNumber>
            &lt;commonProvide:PartNumber xmlns:commonProvide=\"commonentities.xsdobjects.extload\" xmlns:ns1=\"GlobalInteraction.xsdobjects.extload\">60000283&lt;/commonProvide:PartNumber>
         &lt;/commonProvide:ServiceElement2>
      &lt;/ns1:ExtReference>
      &lt;ns1:CustomerLegalName xmlns:ns1=\"GlobalInteraction.xsdobjects.extload\">CLARINS&lt;/ns1:CustomerLegalName>
      &lt;ns1:Type xmlns:ns1=\"GlobalInteraction.xsdobjects.extload\">Global&lt;/ns1:Type>
      &lt;ns1:SubType xmlns:ns1=\"GlobalInteraction.xsdobjects.extload\">National&lt;/ns1:SubType>
   &lt;/ns1:Account>
&lt;/root></ns0:OperationBody>

但要求是我必须在 < 中复制整个输入 XML 结构。和 >。但是我们可以看到额外的命名空间正在复制到它不存在的元素中 请建议我任何解决方案

这是我的 XSLT:

<xsl:stylesheet version=\"2.0\"
    xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"
xmlns:ns0=\"serviceBusiness.xsdobjects.extload\" xmlns:ns1=\"GlobalInteraction.xsdobjects.extload\"
    xmlns:commonProvide=\"commonentities.xsdobjects.extload\"
    exclude-result-prefixes=\"xsl ns1 commonProvide\">


<xsl:template match=\"/\">
<ns0:OperationBody>
  <xsl:apply-templates mode=\"escape\"/>
</ns0:OperationBody>
</xsl:template>
<xsl:template match=\"*\" mode=\"escape\">
<!-- Begin opening tag -->
        <xsl:text>&lt;</xsl:text>
        <xsl:value-of select=\"name()\"/>
        
        <!-- Namespaces -->
<xsl:variable name=\"namespace-in\" select=\"\' xmlns=&quot;GlobalInteraction.xsdobjects.extload&quot;\'\"/>
<xsl:variable name=\"namespace-ns1\" select=\"\' xmlns:ns1=&quot;GlobalInteraction.xsdobjects.extload&quot;\'\"/>
<xsl:variable name=\"namespace-common\" select=\"\' xmlns:commonProvide=&quot;commonentities.xsdobjects.extload&quot;\'\"/>

        <xsl:if test=\"not(ancestor::*)\">
            <xsl:value-of select=\"$namespace-in\"/>
        </xsl:if>
        
        <xsl:for-each select=\"namespace::*[name()=\'ns1\' or name()=\'commonProvide\']\">
            
            <xsl:choose>
                <xsl:when test=\"name()=\'ns1\'\">
                    <xsl:value-of select=\"$namespace-ns1\"/>
                </xsl:when>
                <xsl:when test=\"name()=\'commonProvide\'\">
                    <xsl:value-of select=\"$namespace-common\"/>
                </xsl:when>
            </xsl:choose>
</xsl:for-each>

<!-- End opening tag -->
        <xsl:text disable-output-escaping=\"yes\">&gt;</xsl:text>
        
        <!-- Content (child elements, text nodes, and PIs) -->
        <xsl:apply-templates select=\"node()\" mode=\"escape\" />
        
        <!-- Closing tag -->
        <xsl:text>&lt;/</xsl:text>
        <xsl:value-of select=\"name()\"/>
        <xsl:text disable-output-escaping=\"yes\">&gt;</xsl:text>
    </xsl:template>
    
    <xsl:template match=\"text()\" mode=\"escape\">
        <xsl:call-template name=\"escape-xml\">
            <xsl:with-param name=\"text\" select=\".\"/>
        </xsl:call-template>
</xsl:template>

<xsl:template name=\"escape-xml\">
        <xsl:param name=\"text\"/>
        <xsl:if test=\"$text != \'\'\">
            <xsl:variable name=\"head\" select=\"substring($text, 1, 1)\"/>
            <xsl:variable name=\"tail\" select=\"substring($text, 2)\"/>
            <xsl:choose>
                <xsl:when test=\"$head = \'&amp;\'\">&amp;amp;</xsl:when>
                <xsl:when test=\"$head = \'&lt;\'\">&amp;lt;</xsl:when>
                <xsl:when test=\"$head = \'&gt;\'\"><xsl:value-of select=\"\'&amp;gt;\'\" disable-output-escaping=\"yes\"/></xsl:when>
                <xsl:when test=\"$head = \'&quot;\'\">&amp;quot;</xsl:when>
                <xsl:when test=\"$head = &quot;&apos;&quot;\">&amp;apos;</xsl:when>
                <xsl:otherwise><xsl:value-of select=\"$head\"/></xsl:otherwise>
            </xsl:choose>
            <xsl:call-template name=\"escape-xml\">
                <xsl:with-param name=\"text\" select=\"$tail\"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

    标签: xml xslt-2.0


    【解决方案1】:

    您处理命名空间的逻辑非常奇怪。据我所知,

     <xsl:for-each select="namespace::*[name()='ns1' or name()='commonProvide']">
        
        <xsl:choose>
            <xsl:when test="name()='ns1'">
                <xsl:value-of select="$namespace-ns1"/>
            </xsl:when>
            <xsl:when test="name()='commonProvide'">
                <xsl:value-of select="$namespace-common"/>
            </xsl:when>
        </xsl:choose>
     </xsl:for-each>
    

    是一种相当冗长的写作方式

    <xsl:if test="namespace::ns1">
      <xsl:value-of select="$namespace-ns1"/>
    </xsl:if>
    <xsl:if test="namespace::commonProvide">
      <xsl:value-of select="$namespace-common"/>
    </xsl:if>
    

    这不是问题的直接原因,尽管它暗示您对命名空间轴的工作方式没有很好的理解。

    问题是命名空间轴没有选择命名空间声明在一个元素上,它选择所有范围内命名空间对于元素,包括在父元素上声明的命名空间。消除冗余命名空间的方法是测试它们是否也存在于父元素上:

    <xsl:if test="namespace::ns1 and not(../namespace::ns1)">
    

    ETC

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-14
      • 1970-01-01
      • 1970-01-01
      • 2018-08-08
      • 2015-08-11
      • 1970-01-01
      相关资源
      最近更新 更多