设计模板XSLT来生成XML

时间:2017-07-11 22:44:52

标签: xml xslt

我需要生成这个带有所有东西的xml,每个节点上的名称空间等

<bdo_fosfec:RegistrosPagosElement xsi:type="bdo_fosfec:RegistrosPagos" 
 xmlns:bdo_fosfec="http://asocajas.app.com/example" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <registro54 xsi:type="bdo_fosfec:Registro54">
   <registro82 xsi:type="bdo_fosfec:Registro82">
     <C512>39756656</C512>
     <C614>YAXMINNI</C614>
   </registro82>
 </registro54>
 <registro54 xsi:type="bdo_fosfec:Registro54">
   <registro82 xsi:type="bdo_fosfec:Registro82">
     <C512>79374740</C512>
     <C614>VICTOR</C614>
   </registro82>
 </registro54>
</bdo_fosfec:RegistrosPagosElement>

我构建了一个这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
 <xsl:template match="/">
   <bdo_fosfec:RegistrosPagosElement xsi:type="bdo_fosfec:RegistrosPagos" xmlns:bdo_fosfec="http://asocajas.app.com/example" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <xsl:apply-templates select="registro54"/>
   </bdo_fosfec:RegistrosPagosElement>
 </xsl:template>
 <!--TEMPLATE REGISTRO 54-->
 <xsl:template match="registro54">
   <registro54 xsi:type="bdo_fosfec:Registro54">
        <registro82 xsi:type="bdo_fosfec:Registro82">
          <C512><xsl:value-of select="C512"/></C512>
          <C614><xsl:value-of select="C614"/></C614>
        </registro82>
   </registro54>
 </xsl:template>
</xsl:stylesheet>

但是当我使用XSLT转换 myxml 时,结果xml 不符合预期

结果

 <?xml version="1.0" encoding="utf-8"?>
   <bdo_fosfec:RegistrosPagosElement xsi:type="bdo_fosfec:RegistrosPagos" xmlns:bdo_fosfec="http://asocajas.app.com/example" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />

myxml

 <?xml version="1.0" encoding="utf-8"?>
  <bdo_fosfec_x003A_RegistrosPagosElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <registro54>
     <registro82>
      <C512>123456789</C512>
      <C614>Miguel</C614>
     </registro82>
    </registro54>
    <registro54>
     <registro82>
      <C512>1234567890</C512>
      <C614>Jerónimo</C614>
     </registro82>
    </registro54>
  </bdo_fosfec_x003A_RegistrosPagosElement>

我不知道我做错了什么,我已经尝试删除nameSpace xmlns:xsi =“http://www.w3.org/2001/XMLSchema-instance”xsi:type =“bdo_fosfec:RegistersPages”xmlns:bdo_fosfec =“http://样式表的asocajas.hp.com/bdo_fosfec“但它产生了错误,我也尝试不使用”模板“,结果接近所需的结果,但它与我希望的不一样

Thnks

1 个答案:

答案 0 :(得分:2)

看起来你对上下文感到有点困惑,这导致了错误的XPath选择器。

第一个问题

你从这里开始:

<xsl:template match="/">
    <bdo_fosfec:RegistrosPagosElement xsi:type="bdo_fosfec:RegistrosPagos" xmlns:bdo_fosfec="http://asocajas.app.com/example" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <xsl:apply-templates select="registro54"/>
    </bdo_fosfec:RegistrosPagosElement>
</xsl:template>

所以你对逻辑根元素match进行了编辑。在此逻辑根元素的上下文中,您使用xsl:apply-templates - 但使用select="registro54"。此XPath正在查找作为context元素的直接子元素的任何registro54元素。但是,逻辑根的直接子节点是文件中最顶层的元素,在您的情况下为bdo_fosfec_x003A_RegistrosPagosElement。所以这个select语句不会选择任何内容。

我们可以通过改变两件事之一来解决这个问题。之一:

  1. 将您的xsl:template match声明更改为xsl:template match="/bdo_fosfec_x003A_RegistrosPagosElement"
  2. 将您的xsl:apply-templates select声明更改为xsl:apply-templates select="bdo_fosfec_x003A_RegistrosPagosElement/registro54"
  3. 第二个问题

    即使实施了第一次修复,我们也无法获得所需。你的第二个模板:

    <xsl:template match="registro54">
        <registro54 xsi:type="bdo_fosfec:Registro54">
            <registro82 xsi:type="bdo_fosfec:Registro82">
                <C512><xsl:value-of select="C512"/></C512>
                <C614><xsl:value-of select="C614"/></C614>
            </registro82>
        </registro54>
    </xsl:template>
    

    所以我们的上下文是registro54元素。我们尝试使用这两个语句来获取值:

                <C512><xsl:value-of select="C512"/></C512>
                <C614><xsl:value-of select="C614"/></C614>
    

    这些没有产生任何结果,因为XPath没有选择任何东西。在registro54的上下文中,这些select语句会尝试查找名为registro54C512的{​​{1}}的直接子项。

    但是,如果我们查看您的输入XML:

    C614

    ...我们发现<registro54 xsi:type="bdo_fosfec:Registro54"> <registro82 xsi:type="bdo_fosfec:Registro82"> <C512>39756656</C512> <C614>YAXMINNI</C614> </registro82> </registro54> C512元素是C614的子元素。因此,要实际获取这些值,请将registro82语句更改为:

    select

    结论

    请记住 <C512><xsl:value-of select="registro82/C512"/></C512> <C614><xsl:value-of select="registro82/C614"/></C614> 具有相对XPath(任何不以select开头的XPath表达式,逻辑根)只会从上下文元素的起始点开始选择。