我有以下输入(为简洁起见,不包括完整文件):
input.xml中
<Request>
<EFS>
<child1>
<!-- children -->
</child1>
<child2>
</child2>
<!-- more children etc-->
</EFS>
</Request>
我想删除<Request>
元素,因此<EFS>
成为新的根元素,然后我想为它添加命名空间。我的XSL如下(也缩短了):
我-stylesheet.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
<xsl:output method="xml" indent="yes" version="1.0" encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:copy-of select="@*" copy-namespaces="no" />
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:apply-templates select="node()" />
</xsl:template>
<xsl:template match="EFS">
<xsl:element name="EFS" xmlns="'http://www.EFS-standards.org/standards/PC_Surety/EFS1.6.12/xml/Intake'">
<xsl:call-template name="createEFScontent"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template name="createEFScontent">
<xsl:element name="AuditTotal">
<xsl:element name="TransmissionID" />
<xsl:element name="MessageQuantity" />
<xsl:element name="TotalAmt">0.00</xsl:element>
</xsl:element>
</xsl:template>
<!-- rest of stylesheet -->
删除<Request>
,<EFS>
成为新根。在此之后,我将命名空间应用于<EFS>
,输出如下所示:
的Output.xml
<EFS xmlns="'http://www.EFS-standards.org/standards/PC_Surety/EFS1.6.12/xml/Intake'">
<AuditTotal xmlns="">
<TransmissionID/>
<MessageQuantity/>
<TotalAmt>0.00</com.LibertyMutual_TotalAmt>
</AuditTotal>
<child1 xmlns="">
//children
</child1>
<child2 xmlns="">
<!-- children -->
</child2>
<!-- rest of output -->
我不确定哪里出错了。我希望输出看起来像现在没有xmlns =&#34;&#34;在孩子1和2上。我是否需要添加另一个模板来剥离它们?我在列出的模板中犯了错误吗?
我使用的是SaxonHE 9.7.0-8,这是在转换步骤中从Camel路径中调用的(如果这有任何区别)。另外值得注意的是,它只将空白名称空间应用于子1和2元素。 EFS没有其他子项,但child1和child2的子元素没有xmlns =&#34;&#34;
编辑:在Tim C的回答之后,我已经用他的身份替换了身份模板并添加了模板:
<xsl:template match="@*|text()|comment()|processing-instruction()">
<xsl:copy />
</xsl:template>
这将命名空间应用于EFS。当我添加如下模板时,命名空间在某些元素上显示为空白或者具有完整的命名空间值:
<xsl:template match="EFS/child1/AddRq/Policy">
<xsl:copy>
<xsl:element name="RDDCd">
<xsl:call-template name="getRDDCd" />
</xsl:element>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
运行时,将使用xmlns =&#34;&#34;输出策略。和RDDCd(以及Policy的现有子元素)将包含xmlns =
xsl中有很多这样的模板;我试图复制匹配元素的现有内容,并添加一个新内容,然后返回到身份模板(我认为,我对xsl并不是很好)。我有什么明显的错误吗?我的大多数tempaltes都与源中的元素相匹配,复制内容并添加一个新子项(覆盖样式表中大约70%的模板)。如上所述,我一直在以上述方式创建这些模板,其余的是元素删除:
<template match="MSDCd" />
或更改元素的元素/子元素的值。
答案 0 :(得分:2)
如果要创建新元素,例如AuditTotal
,则需要确保使用新命名空间创建这些元素。你可以这样做..
<xsl:element name="AuditTotal" namespace="http://www.EFS-standards.org/standards/PC_Surety/EFS1.6.12/xml/Intake">
<xsl:element name="TransmissionID" />
<xsl:element name="MessageQuantity" />
<xsl:element name="TotalAmt">0.00</xsl:element>
</xsl:element>
...但是在XSLT中定义默认命名空间以开始
会更容易<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.EFS-standards.org/standards/PC_Surety/EFS1.6.12/xml/Intake"
version="2.0">
此外,对于身份模板,您使用的是xsl:copy
,但这些将复制源文档中没有命名空间的元素,因此它们在输出中也没有命名空间。相反,您还需要在所需的命名空间中创建新元素。
实际上,如果XML中的所有元素都没有命名空间,但您希望输出XML中的所有元素都在命名空间中,则不应在XSLT中的任何位置使用xsl:copy
。你应该用这个替换xsl:copy
..
<xsl:element name="{local-name()}">
试试这个XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.EFS-standards.org/standards/PC_Surety/EFS1.6.12/xml/Intake"
version="2.0">
<xsl:output method="xml" indent="yes" version="1.0" encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*" copy-namespaces="no" />
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>
<xsl:template match="@*|text()|comment()|processing-instruction()">
<xsl:copy />
</xsl:template>
<xsl:template match="/*">
<xsl:apply-templates select="node()" />
</xsl:template>
<xsl:template match="EFS">
<xsl:element name="EFS">
<xsl:call-template name="createEFScontent"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template name="createEFScontent">
<xsl:element name="AuditTotal">
<xsl:element name="TransmissionID" />
<xsl:element name="MessageQuantity" />
<xsl:element name="TotalAmt">0.00</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
您不能只为此使用标准身份模板。您需要模板来匹配每个不同的案例,然后在没有命名空间的情况下复制名称/内容。这样的东西应该有效,但请注意,在你的情况下,它可能无法为你提供空元素(child2
)的预期行为。这包含要复制的每个节点类型的模板,默认情况下将所有内容放入所需的命名空间(样式表根目录中的xmlns
):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0"
xmlns="http://www.EFS-standards.org/standards/PC_Surety/EFS1.6.12/xml/Intake">
<xsl:output method="xml" indent="yes" version="1.0" encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*" />
<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:template match="text()|processing-instruction()|comment()">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="/*">
<xsl:apply-templates select="." />
</xsl:template>
<xsl:template match="EFS">
<xsl:element name="EFS">
<xsl:call-template name="createEFScontent"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template name="createEFScontent">
<xsl:element name="AuditTotal">
<xsl:element name="TransmissionID" />
<xsl:element name="MessageQuantity" />
<xsl:element name="TotalAmt">0.00</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>