我的源xml是:
<?xml version="1.0" encoding="UTF-8"?>
<PMML version="4.1" xmlns="http://www.dmg.org/PMML-4_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.dmg.org/PMML-4_1 pmml-4-1.xsd">
<Header copyright="(C) Copyright IBM Corp. 1989, 2014.">
<Application name="IBM SPSS Statistics 23.0" version="23.0.0.0"/>
</Header>
<GeneralRegressionModel algorithmName="multinomialLogistic" functionName="classification" modelType="multinomialLogistic" targetVariableName="CLASS">
<MiningSchema>
<MiningField missingValueTreatment="asIs" name="CLASS" usageType="predicted"/>
<MiningField missingValueTreatment="asIs" name="ACTIVE_CUSTOMER" usageType="active"/>
<MiningField missingValueTreatment="asIs" name="SEGMENT" usageType="active"/>
</MiningSchema>
<ParameterList>
<Parameter label="Konstanter Term" name="P0000001"/>
<Parameter label="[ACTIVE_CUSTOMER=0]" name="P0000002"/>
<Parameter label="[ACTIVE_CUSTOMER=1]" name="P0000003"/>
<Parameter label="[SEGMENT=0]" name="P00000004"/>
<Parameter label="[SEGMENT=1]" name="P00000005"/>
</ParameterList>
<ParamMatrix>
<PCell beta="-167.307903919999" df="1" parameterName="P0000001" targetCategory="1"/>
<PCell beta="-0.0747629275586869" df="1" parameterName="P0000002" targetCategory="1"/>
<PCell beta="0.409965797830495" df="1" parameterName="P0000003" targetCategory="1"/>
<PCell beta="-1.03190717557433" df="1" parameterName="P0000004" targetCategory="1"/>
<PCell beta="0.904157514089376" df="1" parameterName="P0000005" targetCategory="1"/>
</ParamMatrix>
</GeneralRegressionModel>
</PMML>
我的输出xml是:
<?xml version="1.0" encoding="utf-8"?>
<Predictors xmlns:ns="some:ns" xmlns:rs="http://www.dmg.org/PMML-4_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Predictor coefficient="-167.307903919999" name="__INTERCEPT__" value=""/>
<Predictor coefficient="-0.0747629275586869" name="ACTIVE_CUSTOMER" value="0"/>
<Predictor coefficient="0.409965797830495" name="ACTIVE_CUSTOMER" value="1"/>
<Predictor coefficient="" name="SEGMENT" value="0"/>
<Predictor coefficient="" name="SEGMENT" value="1"/>
</Predictors>
我可以使用以下xslt实现此目的:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sap="http://www.sap.com/sapxsl" xmlns:ns="some:ns" xmlns:rs="http://www.dmg.org/PMML-4_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
<xsl:output encoding="utf-8" indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:key match="rs:ParamMatrix/rs:PCell" name="cell" use="@parameterName"/>
<xsl:key match="rs:DataDictionary/rs:DataField" name="dataField" use="@name"/>
<!-- identity transform -->
<xsl:template match="node()|@*">
<xsl:apply-templates select="node()|@*"/>
</xsl:template>
<xsl:template match="rs:GeneralRegressionModel">
<!--MiningSchema-->
<xsl:apply-templates select="rs:MiningSchema"/>
<!--RegressionTable for predicted targetVariable targetCategory-->
<Predictors>
<xsl:apply-templates select="rs:ParameterList/rs:Parameter"/>
</Predictors>
</xsl:template>
<xsl:template match="rs:Parameter[not(contains(@label, '='))][@name='P0000001']">
<Predictor coefficient="{key('cell', @name)/@beta}" name="__INTERCEPT__" value=""/>
</xsl:template>
<xsl:template match="rs:Parameter[not(contains(@label, '='))][@name!='P0000001']">
<Predictor coefficient="{key('cell', @name)/@beta}" name="{@label}" value=""/>
</xsl:template>
<xsl:template match="rs:Parameter[contains(@label, '=')]" name="split">
<Predictor coefficient="{key('cell', @name)/@beta}" name="{substring-after(substring-before(@label,'='),'[')}" value="{substring-before(substring-after(@label,'='),']')}"/>
</xsl:template>
</xsl:transform>
这个XSLT有效。 但是,我有两个问题: 1.在源xml的开头,有命名空间,例如'xmlns =“http://www.dmg.org/PMML-4_1”',可能是其他值。整个文档只使用这一个命名空间。目前在我的xslt中,我将命名空间设置为固定值'xmlns:rs =“http://www.dmg.org/PMML-4_1”',这是不正确的。如何在xslt中动态设置命名空间?
如果没问题,请你直接修改我的xslt以告诉我用法吗?
非常感谢!!!
答案 0 :(得分:1)
在命名空间中创建一个在运行时才知道的元素:
(a)将任何文字结果元素(例如<Predictor/>
)更改为<xsl:element name="Predictor" namespace="{$ns}'/>
(b)将<xsl:copy/>
的任何使用更改为<xsl:element name="{local-name()}" namespace="{$ns}'/>
(c)使用<xsl:copy-of/>
修改后的身份模板将<xsl:element/>
的任何使用更改为递归副本。
或者,与控制此XML词汇表的人交谈,并询问他们为何以这种方式滥用名称空间。
答案 1 :(得分:0)
如果您正在寻求使xsl命名空间不可知,以便您可以随意更改输入xml的命名空间,那么您需要分两个阶段运行转换。
如果您在xsl中包含以下内容并从xsl中移除所有命名空间引用 - uri和前缀 - (除了您希望在输出中看到的那些)
<xsl:template match="@*" mode="stripNS">
<xsl:attribute name="{local-name(.)}"><xsl:value-of select="."/></xsl:attribute>
</xsl:template>
<xsl:template match="node()" mode="stripNS">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node()|@*" mode="stripNS"/>
</xsl:element>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="nakedXML">
<xsl:apply-templates mode="stripNS"/>
</xsl:variable>
<xsl:apply-templates select="$nakedXML/*" />
</xsl:template>
root上的匹配始终是要执行的初始模板,无论输入命名空间如何。然后xml将使用&lt; xsl:element&gt;和&lt; attribute&gt;要在输入变量$ nakedXML中创建输入xml的表示,将删除所有名称空间。
从这一点开始,您可以使用&lt; apply-templates&gt;反对nakedXML。 注意,一些xsl处理器要求你用一个合适的node-set()函数包装$ nakeXML--每个处理器处理它的方式不同,所以请检查你的文档。
我应该补充一下,我并不完全赞同这种技巧。它对性能有重大影响,剥离命名空间有可能在以后产生混淆。 IMO,当使用命名空间编写内容时,应始终使用该命名空间来引用内容。
答案 2 :(得分:0)
在我之前的回答中发表评论后:
每当您需要获取当前节点的名称空间时,您应该遍历名称空间轴。如果我们假设在根节点中声明了 all 您的docuemnt命名空间,则可以使用xpath“/ * / namespace :: *”来获取所有命名空间的节点集。
因此,对于您的示例输入,类似这样......
<xsl:for-each select="/*/namespace::*">
<namespace prefix="{name()}" uri="{.}"/>
</xsl:for-each>
会给你
<namespace prefix="" uri="http://www.dmg.org/PMML-4_1"/>
<namespace prefix="xsi" uri="http://www.w3.org/2001/XMLSchema-instance"/>
<namespace prefix="xml" uri="http://www.w3.org/XML/1998/namespace"/>
如果您只想要根节点的默认名称空间URI:
<xsl:value-of select="/*/namespace::*[not(name())]"/>
答案 3 :(得分:0)
如果将以下样式表应用于输入XML:
XSLT 1.0(a)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[namespace-uri()=/*/namespace::*[not(name())]]">
<xsl:element name="{local-name()}" namespace="urn:x-my:constant-namespace">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
它会将(未知)默认命名空间中的所有元素移动到已知且常量的命名空间urn:x-my:constant-namespace
:
<?xml version="1.0" encoding="UTF-8"?>
<PMML xmlns="urn:x-my:constant-namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="4.1" xsi:schemaLocation="http://www.dmg.org/PMML-4_1 pmml-4-1.xsd">
<Header copyright="(C) Copyright IBM Corp. 1989, 2014.">
<Application name="IBM SPSS Statistics 23.0" version="23.0.0.0"/>
</Header>
<GeneralRegressionModel algorithmName="multinomialLogistic" functionName="classification" modelType="multinomialLogistic" targetVariableName="CLASS">
<MiningSchema>
<MiningField missingValueTreatment="asIs" name="CLASS" usageType="predicted"/>
<MiningField missingValueTreatment="asIs" name="ACTIVE_CUSTOMER" usageType="active"/>
<MiningField missingValueTreatment="asIs" name="SEGMENT" usageType="active"/>
</MiningSchema>
<ParameterList>
<Parameter label="Konstanter Term" name="P0000001"/>
<Parameter label="[ACTIVE_CUSTOMER=0]" name="P0000002"/>
<Parameter label="[ACTIVE_CUSTOMER=1]" name="P0000003"/>
<Parameter label="[SEGMENT=0]" name="P00000004"/>
<Parameter label="[SEGMENT=1]" name="P00000005"/>
</ParameterList>
<ParamMatrix>
<PCell beta="-167.307903919999" df="1" parameterName="P0000001" targetCategory="1"/>
<PCell beta="-0.0747629275586869" df="1" parameterName="P0000002" targetCategory="1"/>
<PCell beta="0.409965797830495" df="1" parameterName="P0000003" targetCategory="1"/>
<PCell beta="-1.03190717557433" df="1" parameterName="P0000004" targetCategory="1"/>
<PCell beta="0.904157514089376" df="1" parameterName="P0000005" targetCategory="1"/>
</ParamMatrix>
</GeneralRegressionModel>
</PMML>
然后,您可以将第二个样式表应用于结果,例如:
XSLT 1.0(b)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rs="urn:x-my:constant-namespace"
exclude-result-prefixes="rs">
<xsl:output encoding="utf-8" indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:key match="rs:PCell" name="cell" use="@parameterName"/>
<xsl:template match="/">
<Predictors>
<xsl:apply-templates/>
</Predictors>
</xsl:template>
<xsl:template match="rs:Parameter[not(contains(@label, '='))][@name='P0000001']">
<Predictor coefficient="{key('cell', @name)/@beta}" name="__INTERCEPT__" value=""/>
</xsl:template>
<xsl:template match="rs:Parameter[not(contains(@label, '='))][@name!='P0000001']">
<Predictor coefficient="{key('cell', @name)/@beta}" name="{@label}" value=""/>
</xsl:template>
<xsl:template match="rs:Parameter[contains(@label, '=')]">
<Predictor coefficient="{key('cell', @name)/@beta}" name="{substring-after(substring-before(@label,'='),'[')}" value="{substring-before(substring-after(@label,'='),']')}"/>
</xsl:template>
</xsl:stylesheet>
并收到:
<?xml version="1.0" encoding="utf-8"?>
<Predictors>
<Predictor coefficient="-167.307903919999" name="__INTERCEPT__" value=""/>
<Predictor coefficient="-0.0747629275586869" name="ACTIVE_CUSTOMER" value="0"/>
<Predictor coefficient="0.409965797830495" name="ACTIVE_CUSTOMER" value="1"/>
<Predictor coefficient="" name="SEGMENT" value="0"/>
<Predictor coefficient="" name="SEGMENT" value="1"/>
</Predictors>