复制 XML 时删除命名空间并添加新元素

发布于 2025-01-20 20:46:24 字数 2732 浏览 0 评论 0 原文

我有一个简单的 xml,看起来

<ns0:AAA xmlns:ns0="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ITSVersion="XML_1.0">
    <ns0:id extension="USER_TYPE"/>
    <ns0:bb>SOME VALUE</ns0:bb>
    <ns0:cc>OTHER VALUE</ns0:cc>
</ns0:AAA>

我正在尝试在顶级元素 AAA 周围添加一个“包装器”元素,并从上面的 XML。最后在 SOME VALUE 之后添加新元素。

我已尝试为此构建一个 xslt,但不知何故,我无法在复制时删除 ns0 前缀,并且我添加的新元素是通过 xmlns="" 添加的。不确定我做错了什么。

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:urn="http://www.example.com">
<xsl:output method="xml" omit-xml-declaration="yes" />

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>           
    </xsl:copy>
</xsl:template>
    
<xsl:template match="/*">
    <xsl:if test="urn:id[@extension='USER_TYPE']">
         <xsl:element name="WRAPPER" namespace="{namespace-uri()}">
            <xsl:apply-templates select="@* | node()" />
                
                <xsl:element name="cred">
                    <xsl:attribute name="user">test123</xsl:attribute>
                    <xsl:element name="password">
                            <xsl:attribute name="root">n</xsl:attribute>
                    </xsl:element>
                </xsl:element>
        </xsl:element>
    </xsl:if>
    
    <xsl:if test="urn:Id[@extension='ASSET_TYPE']">
        <xsl:element name="WRAPPER" namespace="{namespace-uri()}">
            <xsl:apply-templates select="@* | node()" />
        </xsl:element>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

xslt 的输出看起来像

<WRAPPER xmlns="http://www.example.com" ITSVersion="XML_1.0">
    <ns0:id xmlns:ns0="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" extension="USER_TYPE"/>
    <ns0:bb xmlns:ns0="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">SOME VALUE</ns0:bb>
    <ns0:cc xmlns:ns0="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">OTHER VALUE</ns0:cc>
    <cred xmlns="" user="test123"><password root="n"/></cred>
</WRAPPER>

您可以看到 WRAPPER 元素已正确添加,但所有其他元素都有前缀以及 xmlns 属性,我想删除前缀 ns0<这些元素的 /code> 和 xmlns 属性。我添加的新元素 cred 显示为空的 xmlns

知道我在这里做错了什么吗?

预先感谢您提供任何帮助?

I have a simple xml that looks like

<ns0:AAA xmlns:ns0="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ITSVersion="XML_1.0">
    <ns0:id extension="USER_TYPE"/>
    <ns0:bb>SOME VALUE</ns0:bb>
    <ns0:cc>OTHER VALUE</ns0:cc>
</ns0:AAA>

I am trying to add a "wrapper" element around a top-level element AAA and also remove the name-space prefix ns0 from the above xml. Lastly add new elements after the <ns0:bb>SOME VALUE</ns0:bb>.

I have tried building an xslt for that, but somehow I could not remove the ns0 prefix when copying and the new elements that I have added are added with xmlns="". Not sure what I am doing wrong.

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:urn="http://www.example.com">
<xsl:output method="xml" omit-xml-declaration="yes" />

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>           
    </xsl:copy>
</xsl:template>
    
<xsl:template match="/*">
    <xsl:if test="urn:id[@extension='USER_TYPE']">
         <xsl:element name="WRAPPER" namespace="{namespace-uri()}">
            <xsl:apply-templates select="@* | node()" />
                
                <xsl:element name="cred">
                    <xsl:attribute name="user">test123</xsl:attribute>
                    <xsl:element name="password">
                            <xsl:attribute name="root">n</xsl:attribute>
                    </xsl:element>
                </xsl:element>
        </xsl:element>
    </xsl:if>
    
    <xsl:if test="urn:Id[@extension='ASSET_TYPE']">
        <xsl:element name="WRAPPER" namespace="{namespace-uri()}">
            <xsl:apply-templates select="@* | node()" />
        </xsl:element>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

The output of the xslt looks like

<WRAPPER xmlns="http://www.example.com" ITSVersion="XML_1.0">
    <ns0:id xmlns:ns0="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" extension="USER_TYPE"/>
    <ns0:bb xmlns:ns0="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">SOME VALUE</ns0:bb>
    <ns0:cc xmlns:ns0="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">OTHER VALUE</ns0:cc>
    <cred xmlns="" user="test123"><password root="n"/></cred>
</WRAPPER>

As you can see the WRAPPER element is added correctly, but all the other elements have the prefix and also the xmlns attributes, I want to remove the prefix ns0 and xmlns attributes from those elements. And the new element that I am adding cred shows up with an empty xmlns.

Any idea what I am doing wrong here?

Thanks in Advance for any help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

豆芽 2025-01-27 20:46:24

您所说的“删除名称空间”实际上需要重命名。这意味着您不能使用身份变换模板,该模板保留了所处理的节点

相反,请尝试使用以下路线:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>      
    </xsl:element>
</xsl:template>
    
<xsl:template match="/*">
    <WRAPPER>
        <xsl:apply-templates/>
        <cred user="test123">
            <password root="n"/>
        </cred>
    </WRAPPER>
</xsl:template>

</xsl:stylesheet>

应用于您的示例输入,这将产生:

结果

<?xml version="1.0" encoding="UTF-8"?>
<WRAPPER>
   <id extension="USER_TYPE"/>
   <bb>SOME VALUE</bb>
   <cc>OTHER VALUE</cc>
   <cred user="test123">
      <password root="n"/>
   </cred>
</WRAPPER>

请注意使用文字结果元素

What you call "remove namespace" actually requires renaming. That means you cannot use the identity transform template which preserves the processed nodes as is.

Try instead something along the lines of:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>      
    </xsl:element>
</xsl:template>
    
<xsl:template match="/*">
    <WRAPPER>
        <xsl:apply-templates/>
        <cred user="test123">
            <password root="n"/>
        </cred>
    </WRAPPER>
</xsl:template>

</xsl:stylesheet>

Applied to your example input, this will produce:

Result

<?xml version="1.0" encoding="UTF-8"?>
<WRAPPER>
   <id extension="USER_TYPE"/>
   <bb>SOME VALUE</bb>
   <cc>OTHER VALUE</cc>
   <cred user="test123">
      <password root="n"/>
   </cred>
</WRAPPER>

Note the use of literal result elements.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文