从另一个XML空节点设置默认值(Set default values from another xm

2019-10-20 03:42发布

鉴于:

与数据文件:

<doc>
     <a>some text(<p>text here</p>) or blank</a>
     <b>same</b>
</doc>

默认值文件:

<doc>
     <a><p>Dummy text</p></a>
     <b><p>Dummy text</p></b>
</doc>

我得到这个XSLT以得到第二个文件的默认设置:

$文件=使用默认值文件路径

<a>
    <xsl:choose>
        <xsl:when test="//a!= ''">
            <xsl:copy-of select="//a/p" />
        </xsl:when>
        <xsl:otherwise>
              <xsl:copy-of select="document($file)//a/p" />
        </xsl:otherwise>
    </xsl:choose>
</a>

有了这个它工作得很好,所有的,唯一的问题是,我想通过XML节点进行迭代并进行自动化的过程,以提高可扩展性和节省时间进入每一次来回的每个节点相同的条件下。 但我不能找到一种方法,使用与该变量的XPath 文档()函数文件($文件)$ nodexpath不起作用。

我可能失去了一些东西,只是用XSLT最近才开始,如果有的话,你可以给我一些意见,我将不胜感激。

提前致谢。

编辑:实际的数据更类似于像这样的XML,它可以有更多的走向深沉的水平。

   <doc>
       <object>
          <group1> 
              <a>(<p>text here</p> or blank)</a>
              <b>(<p>text here</p> or blank)</b>
              <c>
                 <c1>(<p>text here</p> or blank)</c1>
                 <c2>(<p>text here</p> or blank)</c2>
              </c>
          </group1>
          <group2>
              <d>(<p>text here</p> or blank)</d>
          </group2>
       </object>
    </doc>

Answer 1:

你可以尝试匹配不包含子元素或者文本和拉断的基于姓名的默认任何元素。

似乎没有成为一个理由去尝试匹配基于您的示例的XPath。 如果您的实际数据比较复杂,更新你的问题,我可以更新我的答案。

例:

XML输入 (由空ab获得默认值。)

<doc>
    <a>some text(<p>text here</p>) or blank</a>
    <a/>
    <b>same</b>
    <b/>
</doc>

so_defaults.xml

<doc>
    <a><p>Dummy text for "a".</p></a>
    <b><p>Dummy text for "b".</p></b>
</doc>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="defaults" select="document('so_defaults.xml')"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*[not(*) and not(text())]">
        <xsl:copy>
            <xsl:apply-templates select="$defaults/*/*[name()=name(current())]/*"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

产量

<doc>
   <a>some text(<p>text here</p>) or blank</a>
   <a>
      <p>Dummy text for "a".</p>
   </a>
   <b>same</b>
   <b>
      <p>Dummy text for "b".</p>
   </b>
</doc>


Answer 2:

我终于解决了,我在这里发布我的解决方案,谢谢丹尼尔的回答,这对我帮助很大:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/*">
        <doc xml:lang="es">
            <object>
                <xsl:apply-templates select="*"/>
            </object>
        </doc>
    </xsl:template> 

    <xsl:template match="*">
        <xsl:copy>
            <xsl:choose>
              <xsl:when test="current() != ''">
                <xsl:choose>
                    <xsl:when test="self::p">
                        <xsl:copy-of select="node()"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="*"/>
                    </xsl:otherwise>
                </xsl:choose>
              </xsl:when>
              <xsl:otherwise>
                <xsl:variable name="file" select="document('template.xml')"/>
                <xsl:copy-of select ="$file//*[name()=name(current())]/p"/>
              </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>


文章来源: Set default values from another xml for empty nodes
标签: xml xslt xpath