XSL中已修改元素的名称空间删除

时间:2015-02-18 02:28:13

标签: xml xslt-1.0 xml-namespaces

我有一个输入XML,其中一个元素架构已更改。因此,根据新架构,我重命名了它。 现在,对于该特定元素,我在输出XML中获得了额外的命名空间。

我使用了排除前缀,但没有删除。我只想要重命名的特定元素被删除名称空间。不知何故,我以前用过的XSL 正在剥离肥皂信封,肥皂体等所有名称空间,而不仅仅是特定元素。

为什么只有更改的元素才会发出命名空间错误。我是否提供了错误的模式声明,为旧元素提供了新模式,(我也怀疑,但更改为旧模式没有任何影响)或任何其他错误。 欢迎提出任何建议。

输入XML的格式是固定的。因此,必须仅在XSLT中进行更改,以删除重命名的元素(PartyDetails元素)之后的额外命名空间。所有其他元素及其命名空间,契约都必须完好无损。

    <?xml version="1.0" encoding="UTF-8"?>
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header />
    <s:Body>
    <MethodResponseType xmlns="http://example.test.com/Trialmethods/Run">
    <MessageResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <ListResponse i:nil="true" />
    <OptionsResponse i:nil="true" />
    <PartyResponse>
    <DemoHolder>
    <Details>
    <ContractType>
    <ID>001</ID>
    <Name>
    <FirstName>Mano</FirstName>
    <Initial>1</Initial>
    </Name>
    </ContractType>
    </Details>
    </DemoHolder>
    </PartyResponse>
    </MessageResponse>
    </MethodResponseType>
    </s:Body>
    </s:Envelope>

用于删除命名空间的XSLT。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
xmlns:ns="http://example.test.com/Trialmethods/Run"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" 
exclude-result-prefixes="ns xsl">

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

<!-- Identity template, provides default behavior that copies all content-->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- More specific template for ns:Details that provides custom behavior -->
<xsl:template match="ns:Details">
    <PartyDetails>
        <xsl:apply-templates select="*" mode="strip"/>
    </PartyDetails>
</xsl:template>

<!-- template to strip out namespaces-->
 <xsl:template match="*" mode="strip">
    <xsl:element name="{local-name()}">
        <xsl:apply-templates select="@*" mode="copy"/>
        <xsl:apply-templates select="*|text()" mode="strip"/>
    </xsl:element>
     </xsl:template>
     </xsl:stylesheet>

在重命名的元素处输出空命名空间。

  <?xml version="1.0" encoding="UTF-8"?>
  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header/>
  <s:Body>
  <MethodResponseType xmlns="http://example.test.com/Trialmethods/Run">
  <MessageResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <ListResponse i:nil="true"/>
    <OptionsResponse i:nil="true"/>
    <PartyResponse>
      <DemoHolder>
        <PartyDetails xmlns=""><ContractType>
            <ID>001</ID>
            <Name>
              <FirstName>Mano</FirstName>
              <Initial>1</Initial>
            </Name>
          </ContractType></PartyDetails>
      </DemoHolder>
    </PartyResponse>
             </MessageResponse>
      </MethodResponseType>
      </s:Body>
      </s:Envelope>

1 个答案:

答案 0 :(得分:1)

很难回答你的问题,你的XML,XSL中似乎存在一些拼写错误,但这里有......

我假设您要翻译的XML输入文档是:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <MyRequest>
            <ns:Details xmlns:ns="www.newschema">
                <ID>123</ID>
                <Name>
                    <FirstName>John</FirstName>
                </Name>
            </ns:Details>
        </MyRequest>
    </soapenv:Body>
</soapenv:Envelope>

如果翻译后您想要的输出XML是:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <MyRequest>
            <PartyDetails>
                <ID>123</ID>
                <Name>
                    <FirstName>John</FirstName>
                </Name>
            </PartyDetails>
        </MyRequest>
    </soapenv:Body>
</soapenv:Envelope>

然后类似下面的XSLT将起作用:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:ns="www.newschema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" exclude-result-prefixes="ns xsl">
    <xsl:template match="/">
        <xsl:apply-templates select="*"/>
    </xsl:template>

    <!-- Identity template, provides default behavior that copies all content into the output -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- More specific template for ns:Details that provides custom behavior -->
    <xsl:template match="ns:Details">
        <PartyDetails>
            <xsl:apply-templates select="*" mode="strip"/>
        </PartyDetails>
    </xsl:template>

    <!-- template to strip out namespaces-->
    <xsl:template match="*" mode="strip">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@*" mode="copy"/>
            <xsl:apply-templates select="*|text()" mode="strip"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

正如我所说,你似乎在XML / XSL中有一些拼写错误

  1. xmlsns:ns代替xmlns:ns
  2. <xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">代替<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  3. <xsl:template match="Details" ns=www.Newschema>代替<xsl:template match="ns:Details">
  4. 好了,因为您已经更新了问题以使用我的XSL,我可以看到您正在谈论的<PartyDetails xmlns="">。如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns="http://example.test.com/Trialmethods/Run" xmlns:ns="http://example.test.com/Trialmethods/Run" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" exclude-result-prefixes="xsl">
        <xsl:template match="/">
            <xsl:apply-templates select="*"/>
        </xsl:template>
        <!-- Identity template, provides default behavior that copies all content-->
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
        <!-- More specific template for ns:Details that provides custom behavior -->
        <xsl:template match="ns:Details">
            <xsl:element name="PartyDetails">
                <xsl:apply-templates select="@*|node()"/>
            </xsl:element>
        </xsl:template>
    </xsl:stylesheet>
    

    我已设置默认命名空间xmlns="http://example.test.com/Trialmethods/Run",但您还需要xmlns:ns="http://example.test.com/Trialmethods/Run"上的匹配ns:Details才能正常工作,以及从ns移除exclude-result-prefixes="xsl" {1}}。我还使用条带模式删除了模板。 对我来说,这会产生输出:

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
        <s:Header/>
        <s:Body>
            <MethodResponseType xmlns="http://example.test.com/Trialmethods/Run">
                <MessageResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                    <ListResponse i:nil="true"/>
                    <OptionsResponse i:nil="true"/>
                    <PartyResponse>
                        <DemoHolder>
                            <PartyDetails>
                                <ContractType>
                                    <ID>001</ID>
                                    <Name>
                                        <FirstName>Mano</FirstName>
                                        <Initial>1</Initial>
                                    </Name>
                                </ContractType>
                            </PartyDetails>
                        </DemoHolder>
                    </PartyResponse>
                </MessageResponse>
            </MethodResponseType>
        </s:Body>
    </s:Envelope>