我正在尝试生成以下形式的 XML 文档:
<?xml version="1.0" encoding="utf-8"?>
<Root xmlns="http://a.example.com">
<Header xmlns="http://b.example.com">
<Fr>
<OrgId>
<Id>hello</Id>
</OrgId>
</Fr>
<To>
<OrgId>
<Id>goodbye</Id>
</OrgId>
</To>
</Header>
</Root>
我有以下 XSLT: 请注意,这是 XSLT 1.0,因为我使用的是 .Net(.Net Framework)
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<Root xmlns="http://a.example.com">
<Header xmlns="http://b.example.com">
<Fr>
<xsl:apply-templates select="/Trades">
<xsl:with-param name="Id">hello</xsl:with-param>
</xsl:apply-templates>
</Fr>
<To>
<xsl:apply-templates select="/Trades">
<xsl:with-param name="Id">goodbye</xsl:with-param>
</xsl:apply-templates>
</To>
</Header>
</Root>
</xsl:template>
<xsl:template match="/Trades">
<xsl:param name="Id" />
<OrgId>
<Id>
<xsl:value-of select="$Id"/>
</Id>
</OrgId>
</xsl:template>
</xsl:stylesheet>
但这会生成以下 XML,该 XML 无法针对第 3 方 XSD 进行验证
<?xml version="1.0" encoding="utf-8"?>
<Root xmlns="http://a.example.com">
<Header xmlns="http://b.example.com">
<Fr>
<OrgId xmlns="">
<Id>hello</Id>
</OrgId>
</Fr>
<To>
<OrgId xmlns="">
<Id>goodbye</Id>
</OrgId>
</To>
</Header>
</Root>
问题是 OrgId xmlns=""。
为什么默认命名空间被显式重置?
我提出的针对 XSD 进行验证的解决方案如下:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<Root xmlns="http://a.example.com">
<Header xmlns="http://b.example.com">
<Fr>
<xsl:apply-templates select="/Trades">
<xsl:with-param name="Id">hellox</xsl:with-param>
<xsl:with-param name="namespace">http://b.example.com</xsl:with-param>
</xsl:apply-templates>
</Fr>
<To>
<xsl:apply-templates select="/Trades">
<xsl:with-param name="Id">goodbye</xsl:with-param>
<xsl:with-param name="namespace">http://b.example.com</xsl:with-param>
</xsl:apply-templates>
</To>
</Header>
</Root>
</xsl:template>
<xsl:template match="/Trades">
<xsl:param name="Id" />
<xsl:param name="namespace" />
<xsl:element name="a:OrgId" namespace="{$namespace}">
<xsl:element name="a:Id" namespace="{$namespace}">
<xsl:value-of select="$Id"/>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这会生成一个 XML 文档:
<?xml version="1.0" encoding="utf-8"?>
<Root xmlns="http://a.example.com">
<Header xmlns="http://b.example.com">
<Fr>
<a:OrgId xmlns:a="http://b.example.com">
<a:Id>hellox</a:Id>
</a:OrgId>
</Fr>
<To>
<a:OrgId xmlns:a="http://b.example.com">
<a:Id>goodbye</a:Id>
</a:OrgId>
</To>
</Header>
</Root>
这是可以接受的,因为它针对 XSD 进行验证,但必须将命名空间传递给模板,并且模板中的所有子元素都需要具有前缀命名空间,这感觉不必要的复杂。
看看这是否适合你(我无法在没有 inout 的情况下测试它):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://b.example.com">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<Root xmlns="http://a.example.com">
<Header xmlns="http://b.example.com">
<Fr>
<xsl:apply-templates select="/Trades">
<xsl:with-param name="Id">hello</xsl:with-param>
</xsl:apply-templates>
</Fr>
<To>
<xsl:apply-templates select="/Trades">
<xsl:with-param name="Id">goodbye</xsl:with-param>
</xsl:apply-templates>
</To>
</Header>
</Root>
</xsl:template>
<xsl:template match="/Trades">
<xsl:param name="Id" />
<OrgId>
<Id>
<xsl:value-of select="$Id"/>
</Id>
</OrgId>
</xsl:template>
</xsl:stylesheet>