查询有关XML到XML的转换

时间:2014-04-21 06:01:38

标签: xml xslt

有两种方法可以将数字放在我的输入xml文件中(注意:输入的非常基本形式):

1.对于1位数:

<xref id="F2">Figure 2</xref>

2.超过1位数:

<xref id="F5">Figures 5</xref>-<xref id="F8">8</xref>

如上所示,错过了外部参照ID 6和7。

现在在我的输出xml文件中,第一个必须保持不变,但第二个必须更改为以下内容:

<xref id="F5 F6 F7 F8">Figures 5-8<xref>

转换代码必须是通用的。不知道这是否可行。欢迎任何帮助或建议。感谢。

2 个答案:

答案 0 :(得分:1)

好的,这是一个XSLT,使用saxon 9测试了如图所示的XML。它现在基于

作为父级,但对于包含外部参照的任何内容都可以修复。

$ java -cp /extra/saxon/saxon9he.jar net.sf.saxon.Transform -s:fig.xml -xsl:fig.xsl

fig.xml:

<data>
  <p>
    <xref id="2">Figure 2</xref>
    <xref id="5">Figures 5</xref>-<xref id="8">8</xref>
    <xref id="10">Figure 10</xref>
    <xref id="15">Figures 15</xref>-<xref id="18">18</xref>
  </p>
</data>

根据修订/详细规格第3次修改 - fig.xsl:

<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xy="/x/y"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                exclude-result-prefixes="xy xs">
<xsl:output method="xml" indent="yes" />

<xsl:template match="*">  
  <xsl:copy>
    <xsl:apply-templates select="*"/>
  </xsl:copy>
</xsl:template>

<xsl:function name="xy:preF" as="xs:string*">
  <xsl:param name = "nums" as="xs:integer*"/>
  <xsl:for-each select="$nums">
    <xsl:value-of select="concat('F',.)"/>
  </xsl:for-each>
</xsl:function>

<xsl:template match="xref[starts-with(text(), 'Figure ')]">  
  <xsl:copy-of select="."/>
</xsl:template>

<xsl:template match="xref[starts-with(text(), 'Figures ')]">
  <xsl:variable name="a" as="xs:integer" select="substring( @id, 2 ) cast as xs:integer"/>
  <xsl:variable name="b" as="xs:integer" select="substring( following-sibling:: [name()='xref'][1]/@id, 2 ) cast as xs:integer"/>
  <xsl:variable name="Fab" as="xs:string*" select="xy:preF($a to $b)"/>
  <xref>
    <xsl:attribute name="id">
      <xsl:value-of select="$Fab"/>
    </xsl:attribute>
    <xsl:value-of select="concat('Figures ',$a,'-',$b)"/>
  </xref>
</xsl:template>

<xsl:template match="xref[not( starts-with(text(), 'Figure'))]">
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

以下styleshet使用XSLT 2.0版:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

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

    <xsl:template match="text()[.='-'][preceding-sibling::*[1][name()='xref']][following-sibling::*[1][name()='xref']]">
        <xsl:variable name="lower" select="preceding-sibling::*[1][name()='xref']/@id"/>
        <xsl:variable name="upper" select="following-sibling::*[1][name()='xref']/@id"/>
        <xref>
            <xsl:attribute name="id">
                <xsl:for-each select="(xs:integer($lower) to xs:integer($upper))">
                    <xsl:if test="position() &gt; 1">
                        <xsl:text> </xsl:text>
                    </xsl:if>
                    <xsl:value-of select="concat('F', .)"/>
                </xsl:for-each>
            </xsl:attribute>
            <xsl:value-of select="preceding-sibling::*[1][name()='xref']"/>
            <xsl:value-of select="."/>
            <xsl:value-of select="following-sibling::*[1][name()='xref']"/>
        </xref>
    </xsl:template>

    <xsl:template match="xref[following-sibling::text()[.='-']]|xref[preceding-sibling::text()[.='-']]"/>
</xsl:stylesheet>

应用于

之类的输入时
<?xml version="1.0" encoding="UTF-8"?>
<data>
    <p>
        <xref id="2">Figure 2</xref>
    </p>
    <p>
        <xref id="5">Figures 5</xref>-<xref id="8">8</xref>
    </p>
</data>

输出是:

<?xml version="1.0" encoding="UTF-8"?>
<data>
   <p>
      <xref id="2">Figure 2</xref>
   </p>
   <p>
      <xref id="F5 F6 F7 F8">Figures 5-8</xref>
   </p>
</data>