Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用xslt生成多个xml文件_Xml_Xslt_Xml Parsing_Xslt 2.0 - Fatal编程技术网

使用xslt生成多个xml文件

使用xslt生成多个xml文件,xml,xslt,xml-parsing,xslt-2.0,Xml,Xslt,Xml Parsing,Xslt 2.0,我正在尝试使用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="ht

我正在尝试使用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>


下面是两个解决方案,尽管我不得不做出一些假设,因为您不清楚自己的需求。第一个解决方案
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! 
t:\ftemp>type soap.xml
0:00:00.084
7.
征用
XML
http://www.taleo.com/ws/tee800/2009/01
1300000华氏度
项目经理
1300000小时
项目经理
130万吨
项目经理
13000018
项目经理
000123
项目经理
130000R
项目经理
13000016
项目经理
t:\ftemp>rmdir/s/q温度
t:\ftemp>调用xslt2soap.xml soap.xsl
t:\ftemp>type temp\section1.xml
1300000华氏度
项目经理
t:\ftemp>dir-temp
驱动器T中的卷为VBOX\u T
卷序列号为0E00-0001
t:\ftemp\temp的目录
2013-08-11 17:00 269 section1.xml
2013-08-11 17:00 269 Section 2.xml
2013-08-11 17:00 269 section3.xml
2013-08-11 17:00 269 section4.xml
2013-08-11 17:00 267 Section 5.xml
2013-08-11 17:00 269 Section 6.xml
2013-08-11 17:00 269 section7.xml
7个文件1881字节
0目录8351150080字节可用
t:\ftemp>键入soap.xsl
t:\ftemp>rmdir/s/q温度
t:\ftemp>调用xslt2soap.xml soap2.xsl
t:\ftemp>type temp\section2.xml
1300000小时
项目经理
t:\ftemp>dir-temp
驱动器T中的卷为VBOX\u T
卷序列号为0E00-0001
t:\ftemp\temp的目录
2013-08-11 17:00 269 section1.xml
2013-08-11 17:00 269 Section 2.xml
2013-08-11 17:00 269 section3.xml
2013-08-11 17:00 269 section4.xml
2013-08-11 17:00 267 Section 5.xml
2013-08-11 17:00 269 Section 6.xml
2013-08-11 17:00 269 section7.xml
7个文件1881字节
0目录8351670272字节可用
t:\ftemp>type soap2.xsl
t:\ftemp>rem完成!

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中的记录元素与导出XML属于同一名称空间时(以及它的所有子体),这是在寻找不属于任何名称空间的记录元素。您应该在这里使用类似的语法(假设您确实事先不知道名称空间)


下一个问题是用于获取“竞赛编号”(和“ManagerRequisitionTitle”)值的代码:


除了在语法上无效外,字段元素也在名称空间中存在同样的问题,因此需要这样做

<xsl:apply-templates select="*[starts-with(local-name(), 'field')][@name='ContestNumber']"/>

虽然这里可能不需要使用xsl:apply模板,但是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文档。相反,此时将其更改为输出一个普通元素

<!-- <xsl:result-document href="{$pDest}section{position()}.xml"> -->
<file href="{$pDest}section{position()}.xml">
   <JobPositionPostings>...</JobPositionPostings>
</file>

...

然后,使用XSLT测试工具(如)测试XML和修改后的XSLT,查看是否创建了多个文件元素。如果是,,您应该可以改回使用xsl:result document

我认为单靠xslt解析即使不是不可能也很难做到……谢谢您的回复。但我的问题仍然没有解决。我使用了您建议的第一个xslt,但我没有得到任何输出。我认为这句话没有返回任何结果事情由于名字空间在其中。是否有任何名称空间绑定标签的解决方案被视为根标签。模板应该匹配元素,而不管名称空间,如答案中所解释的。除了问题中显示的模板之外,您的XSLT还有其他模板吗?请注意,我已经修改了我的答案,以显示您如何可能测试模板是否实际匹配任何内容。嗨,蒂姆,再次感谢你。你真的帮了我很多。现在我正在恢复正常
<xsl:apply-templates select="*[starts-with(local-name(), 'field')][@name='ContestNumber']"/>
<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>
<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>
<!-- <xsl:result-document href="{$pDest}section{position()}.xml"> -->
<file href="{$pDest}section{position()}.xml">
   <JobPositionPostings>...</JobPositionPostings>
</file>