XSLT:在xml中第一个标记<poslog>之后从元素中删除名称空间前缀

时间:2017-09-26 20:42:02

标签: xslt xslt-1.0

我们要求在XML内容中删除前缀<dsr:LineItemItems>6</dsr:LineItemItems>,当我们使用下面的代码时,它成功地从xml元素中删除了前缀“dsr”,但我们需要输出xml有效负载中的xmlns名称空间。存在于POSLog标记中。

还需要输出xml中输入第一个标记<POSLog>中的所有名称空间/内容。

输入xml:

<?xml version="1.0" encoding="utf-8"?>
<POSLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dsr="http://www.dsr.com/rsd/tlog/markup/poslog" xsi:schemaLocation="http://www.nrf-arts.org/IXRetail/namespace/ POSLog.xsd http://www.dsr.com/rsd/tlog/markup/poslog DSRPOSLog.xsd" xmlns="http://www.nrf-arts.org/IXRetail/namespace/">
 <dsr:LineItemItems>6</dsr:LineItemItems>

XSL代码:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dsr="http://www.dsr.com/rsd/tlog/markup/poslog" xsi:schemaLocation="http://www.nrf-arts.org/IXRetail/namespace/ POSLog.xsd 
http://www.dsr.com/rsd/tlog/markup/poslog DSRPOSLog.xsd" xmlns="http://www.nrf-arts.org/IXRetail/namespace/" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" />
        <xsl:template match="*">
        <xsl:element name="{local-name()}" >
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

xsl代码输出xml:

<?xml version="1.0" encoding="UTF-8"?>
<POSLog schemaLocation="http://www.nrf-arts.org/IXRetail/namespace/ POSLog.xsd http://www.dsr.com/rsd/tlog/markup/poslog DSRPOSLog.xsd">
 <LineItemItems>6</LineItemItems>

需要输出如下所示的所有名称空间而不更改第一个标记

<?xml version="1.0" encoding="UTF-8"?>
<POSLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dsr="http://www.dsr.com/rsd/tlog/markup/poslog" xsi:schemaLocation="http://www.nrf-arts.org/IXRetail/namespace/ POSLog.xsd http://www.dsr.com/rsd/tlog/markup/poslog DSRPOSLog.xsd" xmlns="http://www.nrf-arts.org/IXRetail/namespace/">
      <LineItemItems>6</LineItemItems>

谢谢, 拉维

2 个答案:

答案 0 :(得分:0)

在结果树中有三种创建元素的方法,它们在处理命名空间方面有所不同:

  • xsl:element创建一个没有名称空间的元素,而不是元素名称及其属性名称中使用的名称空间
  • xsl:copy复制您正在复制的源元素上存在的所有命名空间,无论它们是否实际使用
  • 文字结果元素(例如<POSLog>)复制样式表中元素范围内的所有名称空间,而不是使用exclude-result-prefixes排除的名称空间

因此,您希望使用xsl:copy或文字结果元素创建结果文档的最外层元素,而不是使用xsl:element

您遇到的另一个问题是您已将xsi:schemaLocation重命名为schemaLocation。发生这种情况是因为您使用了<xsl:attribute name="{local-name()}"/>。这里最好只使用xsl:copy-of来复制属性。

答案 1 :(得分:0)

添加额外的模板以匹配文档元素并复制它,而不是重构没有名称空间的新元素。在现有模板匹配元素中,添加一个属性以指示xsl:element构造函数中的命名空间。

以下样式表确保所有元素都绑定到命名空间http://www.nrf-arts.org/IXRetail/namespace/,并保留命名空间前缀dsr

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dsr="http://www.dsr.com/rsd/tlog/markup/poslog" xsi:schemaLocation="http://www.nrf-arts.org/IXRetail/namespace/ POSLog.xsd 
    http://www.dsr.com/rsd/tlog/markup/poslog DSRPOSLog.xsd" >
    <xsl:output method="xml" version="1.0" encoding="UTF-8" />

<!-- copy the document element, preserving it's namespaces -->
    <xsl:template match="/*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

 <!--create elements using the local-name, but bound to the desired namespace -->   
    <xsl:template match="*">
        <xsl:element name="{local-name()}" namespace="http://www.nrf-arts.org/IXRetail/namespace/" >
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>