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
中似乎有一些拼写错误
xmlsns:ns
而不是 xmlns:ns
<xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
而不是 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<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>
我有一个输入 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
中似乎有一些拼写错误xmlsns:ns
而不是xmlns:ns
<xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
而不是<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<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>