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

Namespace removal for modified element in XSL

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

我使用了排除前缀,但它没有被删除。我只想要被重命名的特定元素被删除的命名空间。不知何故,我之前使用的XSL 正在剥离 soap envelope、soap body 等处的所有名称空间,而不仅仅是针对特定元素。

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

输入格式 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>

很难理解您的问题,而且您的 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">

好的,既然你已经更新了你的问题以使用我的 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"。我还删除了带条模式的模板。 对我来说,这会产生输出:

<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>