【问题标题】:Design Template XSLT to generate XML设计模板 XSLT 以生成 XML
【发布时间】:2017-12-16 04:04:55
【问题描述】:

我需要用所有东西、每个节点上的命名空间等生成这个 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 时,result 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>

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

谢谢

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    您似乎对上下文有些困惑,这会导致 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>
    

    所以你matched 在逻辑根元素上。在此逻辑根元素的上下文中,您使用xsl:apply-templates——但使用select="registro54"。此 XPath 正在寻找作为上下文元素的直接子元素的任何 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"

    第二个问题

    即使在实施了第一个修复后,我们也没有得到我们需要的东西。你的第二个模板:

    <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 语句试图找到registro54 的直接子代,它们被命名为C512C614

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

    <registro54 xsi:type="bdo_fosfec:Registro54">
        <registro82 xsi:type="bdo_fosfec:Registro82">
            <C512>39756656</C512>
            <C614>YAXMINNI</C614>
        </registro82>
    </registro54>
    

    ... 我们看到 C512C614 元素是 registro82 的子元素。因此,要实际获取这些值,请将您的 select 语句更改为:

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

    结论

    请记住,带有相对 XPath 的 select(任何不以 / 开头的 XPath 表达式,即逻辑根)只会从上下文元素的起点进行选择。

    【讨论】:

    • 您对第一个问题的建议修复将不起作用,因为输入 xml 的根元素不在命名空间中,因此您的 xpath 不会匹配/选择任何内容。
    • 你说得对@DanielHaley,我已经编辑了你的答案以适应第一个问题和第二个问题的“myxml”。感谢您的回答,它对我帮助很大,是的,您是对的,我在 XSLT 文件中遇到了几个问题。哈,你的回答也是正确的。谢谢!
    • @DanielHaley -- 感谢您的完整性检查。我使用 Saxon HE 9.6.0.7 在 OxygenXML 中对其进行了全部测试,并且更改 select 工作得很好——但是在各种中断之间,我忘了提到 bdo_fosfec: 前缀的命名空间声明必须在更改 @ 之前移动987654350@。我马上编辑。
    • @EiríkrÚtlendi - 输入的根元素(问题中的myxml)实际上是bdo_fosfec_x003A_RegistrosPagosElement(注意根本没有命名空间前缀)。听起来像 OP 已经弄清楚了,但没什么大不了的。 +1
    • @Makitodev,为我之前的困惑道歉。您提议进行编辑以修复 Daniel 刚刚评论的内容,而我在查看您的编辑时引用了错误的 XML —— 我错误地查看了所需的输出,而不是 myxml 输入。我会修复我的帖子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 2014-08-17
    • 2010-09-24
    • 1970-01-01
    • 2014-08-23
    • 2019-08-01
    相关资源
    最近更新 更多