我有以下输入为XML:
<?xml version="1.0" encoding="UTF-8"?>
<Header xmlns="http://www.oracle.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.oracle.com/webfolder/1/ http://www.oracle.com/webfolder/1/aXML.xsd" creator="mine">
<SubHead1 values="1">
<CoverPage>
<Number>324</Number>
<Status>test</Status>
<ChangeType>test</ChangeType>
<DescriptionOfChange>test</DescriptionOfChange>
<ReasonForChange>test</ReasonForChange>
<ReasonCode>test</ReasonCode>
<Workflow>test</Workflow>
</CoverPage>
<PageTwo>
<single1>No</single1>
<single2>No</single2>
<multisingle2>
<Value>r</Value>
<Value>i</Value>
<Value>h</Value>
<Value>m</Value>
</multisingle2>
<CreateUser>mine</CreateUser>
<Date01>2016-04-08T18:30:58Z</Date01>
</PageTwo>
</SubHead1>
<SubHead2 values="2">
<TitleBlock>
<Number>22</Number>
<PartType>Part</PartType>
<LifecyclePhase>Preliminary</LifecyclePhase>
<Description>TEST</Description>
<Rev>88</Rev>
</TitleBlock>
<PageTwo>
<single1>z</single1>
<single2>a</single2>
<multisingle1>
<Value>b</Value>
<Value>c</Value>
<Value>d</Value>
</multisingle1>
<multisingle2>
<Value>7</Value>
<Value>ac</Value>
</multisingle2>
<single3>f</single3>
<CreateUser>mine</CreateUser>
<Date01>2016-04-27T17:31:44Z</Date01>
</PageTwo>
</SubHead2>
</Header>
使用以下XSLT,我能够生成输出:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.oracle.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://www.oracle.com/webfolder/1/ http://www.oracle.com/webfolder/1/aXML.xsd">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
<Header>
<SubHead2>
<xsl:attribute name="values">
<xsl:value-of select="/*/*[2]/@values" />
</xsl:attribute>
<xsl:apply-templates select="/*/*[2]/*[1]/*" />
<xsl:for-each select="/*/*[2]/*[2]/*">
<xsl:variable name="j" select="position()" />
<xsl:if test="/*/*[2]/*[2]/*[$j] and not(/*/*[2]/*[2]/*[$j]/*)">
<xsl:copy-of select="/*/*[2]/*[2]/*[$j]" />
</xsl:if>
<xsl:for-each select="/*/*[2]/*[2]/*/*">
<xsl:variable name="i" select="position()" />
<xsl:if test="$i = 1">
<xsl:apply-templates select="/*/*[2]/*/*[$j][*[2]]">
<xsl:with-param name="testParam3" select="$i" />
</xsl:apply-templates>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
<SubHead1>
<xsl:apply-templates select="/*/*[1]/*[1]/*" />
</SubHead1>
</SubHead2>
<xsl:for-each select="/*/*[2]/*[2]/*">
<xsl:variable name="j" select="position()" />
<xsl:for-each select="*">
<xsl:variable name="i" select="position()" />
<xsl:if test="$i > 1">
<xsl:call-template name="attr">
<xsl:with-param name="testParam1" select="$j" />
<xsl:with-param name="testParam2" select="$i" />
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</Header>
</xsl:template>
<xsl:template match="/*/*[2]/*/*[*[2]]">
<xsl:copy>
<xsl:copy-of select="@* | *[1]" />
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy-of select="." />
</xsl:template>
<xsl:template match="/*/*[2]/*/*[*[2]]">
<xsl:param name="testParam3" />
<xsl:copy>
<xsl:copy-of select="@* | *[$testParam3]" />
</xsl:copy>
</xsl:template>
<xsl:template name="attr">
<xsl:param name="testParam1" />
<xsl:param name="testParam2" />
<SubHead2>
<xsl:attribute name="uniqueId">
<xsl:value-of select="/*/*[2]/@values" />
</xsl:attribute>
<Number>
<xsl:value-of select="/*/*[2]/*[1]/*[1]" />
</Number>
<xsl:apply-templates select="/*/*[2]/*/*[$testParam1][*[2]]">
<xsl:with-param name="testParam3" select="$testParam2" />
</xsl:apply-templates>
</SubHead2>
</xsl:template>
</xsl:stylesheet>
输出(XML):
<?xml version="1.0" encoding="UTF-8"?>
<Header xmlns="http://www.oracle.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SubHead2 values="2">
<Number>22</Number>
<PartType>Part</PartType>
<LifecyclePhase>Preliminary</LifecyclePhase>
<Description>TEST</Description>
<Rev>88</Rev>
<single1>z</single1>
<single2>a</single2>
<multisingle1>
<Value>b</Value>
</multisingle1>
<multisingle2>
<Value>7</Value>
</multisingle2>
<single3>f</single3>
<CreateUser>mine</CreateUser>
<Date01>2016-04-27T17:31:44Z</Date01>
<SubHead1>
<Number>324</Number>
<Status>test</Status>
<ChangeType>test</ChangeType>
<DescriptionOfChange>test</DescriptionOfChange>
<ReasonForChange>test</ReasonForChange>
<ReasonCode>test</ReasonCode>
<Workflow>test</Workflow>
</SubHead1>
</SubHead2>
<SubHead2 uniqueId="2">
<Number>22</Number>
<multisingle1>
<Value>c</Value>
</multisingle1>
</SubHead2>
<SubHead2 uniqueId="2">
<Number>22</Number>
<multisingle1>
<Value>d</Value>
</multisingle1>
</SubHead2>
<SubHead2 uniqueId="2">
<Number>22</Number>
<multisingle2>
<Value>ac</Value>
</multisingle2>
</SubHead2>
</Header>
在输出中,您可以看到我无法在“标题”元素中包含“creator”属性
问题是我无法控制传入的XML,因为命名空间值可以与新属性一起动态生成
例如:(动态根元素)
<Header xmlns="http://www.oracle.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.oracle.com/webfolder/1/ http://www.oracle.com/webfolder/1/aXML.xsd" foo="bar">
<Header xmlns="http://www.ex.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.sample.com/ex/ http://www.sample.com/ex/foo.xsd">
我想使用Root节点生成与输入XML
相同的输出任何帮助都会有用
由于
答案 0 :(得分:0)
如果你真的想要处理带有不同命名空间的XML文档,你可以做的是首先定义一个变量来存储传入文档的命名空间uri(这假设XML文档只有命名空间)
<xsl:variable name="namespace" select="namespace-uri(/*)" />
然后使用<Header>
并指定命名空间而不是xsl:element
来创建元素
<xsl:element name="Header" namespace="{$namespace}">
您必须为您创建的每个静态元素执行此操作
试试这个简化的XML作为例子
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.oracle.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://www.oracle.com/webfolder/1/ http://www.oracle.com/webfolder/1/aXML.xsd">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:variable name="namespace" select="namespace-uri(/*)" />
<xsl:template match="/*">
<xsl:element name="Header" namespace="{$namespace}">
<xsl:copy-of select="namespace::*" />
<xsl:copy-of select="@*" />
<xsl:element name="SubHead2" namespace="{$namespace}">
<xsl:attribute name="values">
<xsl:value-of select="/*/*[2]/@values" />
</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>