我正在尝试使用xslt生成多个xml文件。 我的* input.xm * l文件是
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
<soapenv:Body>
<ns1:getDocumentByKeyResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://www.taleo.com/ws/integration/toolkit/2005/07">
<Document xmlns="http://www.taleo.com/ws/integration/toolkit/2005/07">
<Attributes>
<Attribute name="duration">0:00:00.084</Attribute>
<Attribute name="count">7</Attribute>
<Attribute name="entity">Requisition</Attribute>
<Attribute name="mode">XML</Attribute>
<Attribute name="version">http://www.taleo.com/ws/tee800/2009/01</Attribute>
</Attributes>
<Content>
<ExportXML xmlns="http://www.taleo.com/ws/integration/toolkit/2005/07">
<record>
<field name="ContestNumber">1300000F</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">1300000H</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">1300000T</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">13000018</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">000123</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">1300000R</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">13000016</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
</ExportXML>
</Content>
</Document>
</ns1:getDocumentByKeyResponse>
</soapenv:Body>
</soapenv:Envelope>
我的xslt是sample.xslt
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pDest" select="'file:///c:/temp/'"/>
<xsl:template match="*[starts-with(name(),'ExportXML')]">
<xsl:for-each select="record">
<xsl:result-document href="{$pDest}section{position()}.xml">
<JobPositionPostings>
<JobPositionPosting>
<xsl:apply-templates select="*:field[starts-with(@name,'ContestNumber')]"/>
<JobDisplayOptions>
<xsl:apply-templates select="*:field[starts-with(@name,'ManagerRequisitionTitle')]"/>
</JobDisplayOptions>
</JobPositionPosting>
</JobPositionPostings>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我没有得到正确的输出。我希望每个输入标签数据都包含在这样的单独文件中
<?xml version="1.0" encoding="UTF-8"?>
</JobPositionPostings>
<JobPositionPostings>
<JobPositionPosting>
<contestnumber>13000016</contestnumber>
<JobDisplayOptions>
<managerrequisitiontitle>Project Manager</managerrequisitiontitle>
</JobDisplayOptions>
</JobPositionPosting>
</JobPositionPostings>
请提前告诉我任何解决方案。谢谢。
答案 0 :(得分:1)
下面有两个解决方案,但我不得不做一些假设,因为你不清楚你的要求。第一个解决方案soap.xsl
使用拉式样式,其中元素在样式表中显示。第二个解决方案soap2.xsl
使用推送样式,其中元素是从属性名称合成的。在涵盖这些基础知识之后,我还不知道你还想用你的样式表做些什么。
t:\ftemp>type soap.xml
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns1:getDocumentByKeyResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://www.taleo.com/ws/integration/toolkit/2005/07">
<Document xmlns="http://www.taleo.com/ws/integration/toolkit/2005/07">
<Attributes>
<Attribute name="duration">0:00:00.084</Attribute>
<Attribute name="count">7</Attribute>
<Attribute name="entity">Requisition</Attribute>
<Attribute name="mode">XML</Attribute>
<Attribute name="version">http://www.taleo.com/ws/tee800/2009/01</Attribute>
</Attributes>
<Content>
<ExportXML xmlns="http://www.taleo.com/ws/integration/toolkit/2005/07">
<record>
<field name="ContestNumber">1300000F</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">1300000H</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">1300000T</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">13000018</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">000123</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">1300000R</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
<record>
<field name="ContestNumber">13000016</field>
<field name="ManagerRequisitionTitle">Project Manager</field>
</record>
</ExportXML>
</Content>
</Document>
</ns1:getDocumentByKeyResponse>
</soapenv:Body>
</soapenv:Envelope>
t:\ftemp>rmdir /s /q temp
t:\ftemp>call xslt2 soap.xml soap.xsl
t:\ftemp>type temp\section1.xml
<JobPositionPostings>
<JobPositionPosting>
<contestnumber>1300000F</contestnumber>
<JobDisplayOptions>
<managerrequisitiontitle>Project Manager</managerrequisitiontitle>
</JobDisplayOptions>
</JobPositionPosting>
</JobPositionPostings>
t:\ftemp>dir temp
Volume in drive T is VBOX_t
Volume Serial Number is 0E00-0001
Directory of t:\ftemp\temp
2013-08-11 17:00 269 section1.xml
2013-08-11 17:00 269 section2.xml
2013-08-11 17:00 269 section3.xml
2013-08-11 17:00 269 section4.xml
2013-08-11 17:00 267 section5.xml
2013-08-11 17:00 269 section6.xml
2013-08-11 17:00 269 section7.xml
7 File(s) 1,881 bytes
0 Dir(s) 8,351,150,080 bytes free
t:\ftemp>type soap.xsl
<xsl:stylesheet version="2.0"
xpath-default-namespace="http://www.taleo.com/ws/integration/toolkit/2005/07"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pDest" select="'temp/'"/>
<xsl:template match="/">
<xsl:for-each select="//record">
<xsl:result-document href="{$pDest}section{position()}.xml">
<JobPositionPostings>
<JobPositionPosting>
<contestnumber>
<xsl:value-of select="field[@name='ContestNumber']"/>
</contestnumber>
<JobDisplayOptions>
<managerrequisitiontitle>
<xsl:value-of select="field[@name='ManagerRequisitionTitle']"/>
</managerrequisitiontitle>
</JobDisplayOptions>
</JobPositionPosting>
</JobPositionPostings>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
t:\ftemp>rmdir /s /q temp
t:\ftemp>call xslt2 soap.xml soap2.xsl
t:\ftemp>type temp\section2.xml
<JobPositionPostings>
<JobPositionPosting>
<contestnumber>1300000H</contestnumber>
<JobDisplayOptions>
<managerrequisitiontitle>Project Manager</managerrequisitiontitle>
</JobDisplayOptions>
</JobPositionPosting>
</JobPositionPostings>
t:\ftemp>dir temp
Volume in drive T is VBOX_t
Volume Serial Number is 0E00-0001
Directory of t:\ftemp\temp
2013-08-11 17:00 269 section1.xml
2013-08-11 17:00 269 section2.xml
2013-08-11 17:00 269 section3.xml
2013-08-11 17:00 269 section4.xml
2013-08-11 17:00 267 section5.xml
2013-08-11 17:00 269 section6.xml
2013-08-11 17:00 269 section7.xml
7 File(s) 1,881 bytes
0 Dir(s) 8,351,670,272 bytes free
t:\ftemp>type soap2.xsl
<xsl:stylesheet version="2.0"
xpath-default-namespace="http://www.taleo.com/ws/integration/toolkit/2005/07"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pDest" select="'temp/'"/>
<xsl:template match="/">
<xsl:for-each select="//record">
<xsl:result-document href="{$pDest}section{position()}.xml">
<JobPositionPostings>
<JobPositionPosting>
<xsl:apply-templates select="field[@name='ContestNumber']"/>
<JobDisplayOptions>
<xsl:apply-templates
select="field[@name='ManagerRequisitionTitle']"/>
</JobDisplayOptions>
</JobPositionPosting>
</JobPositionPostings>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
<xsl:template match="field">
<xsl:element name="{lower-case(@name)}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
t:\ftemp>rem Done!
答案 1 :(得分:0)
你的XSLT遇到了一些问题,主要是名称空间。您从以下模板匹配开始
<xsl:template match="*[starts-with(name(),'ExportXML')]">
这很好,但是如果你知道 ExportXML 元素属于一个命名空间(在你的情况下它就是这样),你真的只需要这样做,但是不要命名空间。理想情况下,您应该在这里使用“local-name()”,而不是“name()”,因为name()将包含任何名称空间前缀,因此在以下情况下不起作用。
<x:ExportXML xmlns:x="http://www.taleo.com/ws/integration/toolkit/2005/07">
无论如何,您的下一行XSLT
会出现问题<xsl:for-each select="record">
当XML中的记录元素与 ExportXML 属于同一名称空间时,这正在寻找记录元素不属于任何命名空间的一部分强>(和它的所有后代一样)。你应该在这里使用类似的语法(假设你真的不提前知道命名空间)
<xsl:for-each select="*[starts-with(local-name(),'record')]">
下一个问题是您使用的代码来获取“ContestNumber”(和“ManagerRequisitionTitle”)的值:
<xsl:apply-templates select="*:field[starts-with(@name,'ContestNumber')]"/>
除了在语法上无效之外,你也有同样的问题, field 元素也在命名空间中,所以你需要这样做
<xsl:apply-templates select="*[starts-with(local-name(), 'field')][@name='ContestNumber']"/>
虽然此处可能不需要使用 xsl:apply-templates ,但 xsl:value-of 应该这样做。
试试这个XSLT
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pDest" select="'file:///c:/temp/'"/>
<xsl:template match="*[starts-with(local-name(),'ExportXML')]">
<xsl:for-each select="*[starts-with(local-name(),'record')]">
<xsl:result-document href="{$pDest}section{position()}.xml">
<JobPositionPostings>
<JobPositionPosting>
<xsl:value-of select="*[starts-with(local-name(), 'field')][@name='ContestNumber']"/>
<JobDisplayOptions>
<xsl:value-of select="*[starts-with(local-name(), 'field')][@name='ManagerRequisitionTitle']"/>
</JobDisplayOptions>
</JobPositionPosting>
</JobPositionPostings>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
<xsl:template match="*[starts-with(local-name(), 'Attributes')]"/>
</xsl:stylesheet>
还要注意要匹配的模板,并忽略属性,否则XSLT的内置模板会匹配这些模板,并输出文本值。
当然,如果您现在确实命名空间始终是相同的,那么您可以通过声明命名空间来简化XSLT。这个XSLT也应该有效:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.taleo.com/ws/integration/toolkit/2005/07">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pDest" select="'file:///c:/temp/'"/>
<xsl:template match="ExportXML">
<xsl:for-each select="record">
<xsl:result-document href="{$pDest}section{position()}.xml">
<JobPositionPostings>
<JobPositionPosting>
<xsl:value-of select="field[@name='ContestNumber']"/>
<JobDisplayOptions>
<xsl:value-of select="field[@name='ManagerRequisitionTitle']"/>
</JobDisplayOptions>
</JobPositionPosting>
</JobPositionPostings>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
<xsl:template match="Attributes"/>
</xsl:stylesheet>
编辑:测试模板的一种方法是匹配是暂时将XSLT更改为不使用 xsl:result-document 。相反,将其更改为此时输出普通元素
<!-- <xsl:result-document href="{$pDest}section{position()}.xml"> -->
<file href="{$pDest}section{position()}.xml">
<JobPositionPostings>...</JobPositionPostings>
</file>
然后,使用XSLT测试工具(例如http://xslttest.appspot.com/)并测试XML并修改XSLT,以查看是否正在创建多个文件元素。如果是这样,您应该可以改回使用 xsl:result-document 。