2

我有一个 xml 文件,并希望使用具有复杂规则的 xslt 来翻译它。源xml是这样的:

<analysis>
    <blocks>
        <block id="35" original="5,13">
            <contain>6 ,7</contain>
        </block>
        <block id="33" original="20">
            <contain>11, 8, 9, 10</contain>
        </block>
    </blocks>
    <images>
        <image id = "11">./img/a.jpg </image>
    </images>
    <lines>
        <line id="6"/>
            <char font="2">a</char>
            <char font="2">a</char>
            <char font="2">a</char>
            <char font="2">a</char>
        <line id="7"/>
            <char font="2">b</char>
            <char font="2">b</char>
            <char font="2">b</char>
            <char font="2">b</char>
        <line id="8"/>
            <char font="2">c</char>
            <char font="2">c</char>
            <char font="2">c</char>
            <char font="2">c</char>
        <line id="9"/>
            <char font="2">d</char>
            <char font="2">d</char>
            <char font="2">d</char>
            <char font="2">d</char>
        <line id="10"/>
            <char font="2">e</char>
            <char font="2">e</char>
            <char font="2">e</char>
            <char font="2">e</char>
    </lines>
</analysis>

结果xml是:

<result>
    <block id="35">
        <text>
            aaaabbbb
        </text>
    </block>
    <block id="33">
        <text>
            cccc
        </text>
        <image ref="./img/a.jpg"/>
        <text>
            ddddeeee
        </text>
    </block>
</result>

规则是:在“block”标签下,有“contain”标志,其内容是block引用的id集合。

4

2 回答 2

1

问题中唯一没有意义的部分是输出img中两个text元素之间的结果如何。

这是一个 XSLT 2.0 示例。这并不准确,但可能足够接近您进行修改以实现您需要的内容。

XML 输入

<analysis>
    <blocks>
        <block id="35" original="5,13">
            <contain>6 ,7</contain>
        </block>
        <block id="33" original="20">
            <contain>11, 8, 9, 10</contain>
        </block>
    </blocks>
    <images>
        <image id = "11">./img/a.jpg </image>
    </images>
    <lines>
        <line id="6"/>
            <char font="2">a</char>
            <char font="2">a</char>
            <char font="2">a</char>
            <char font="2">a</char>
        <line id="7"/>
            <char font="2">b</char>
            <char font="2">b</char>
            <char font="2">b</char>
            <char font="2">b</char>
        <line id="8"/>
            <char font="2">c</char>
            <char font="2">c</char>
            <char font="2">c</char>
            <char font="2">c</char>
        <line id="9"/>
            <char font="2">d</char>
            <char font="2">d</char>
            <char font="2">d</char>
            <char font="2">d</char>
        <line id="10"/>
            <char font="2">e</char>
            <char font="2">e</char>
            <char font="2">e</char>
            <char font="2">e</char>
    </lines>
</analysis>

XSLT 2.0

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

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

    <xsl:template match="/">
        <results>
            <xsl:apply-templates select="analysis/blocks/block"/>
        </results>
    </xsl:template>

    <xsl:template match="block">
        <xsl:copy>
            <xsl:apply-templates select="@*[not(name()='original')]"/>
            <xsl:apply-templates select="/*/*/image[@id=tokenize(current()/contain,'\s*,\s*')]"/>
            <text>
                <xsl:apply-templates select="/*/*/line[@id=tokenize(current()/contain,'\s*,\s*')]/following-sibling::char[preceding-sibling::line[1][@id=tokenize(current()/contain,'\s*,\s*')]]/text()"/>
            </text>         
        </xsl:copy>     
    </xsl:template>

    <xsl:template match="image">
        <image ref="{normalize-space(.)}"/>
    </xsl:template>

</xsl:stylesheet>

XML 输出

<results>
   <block id="35">
      <text>aaaabbbb</text>
   </block>
   <block id="33">
      <image ref="./img/a.jpg"/>
      <text>ccccddddeeee</text>
   </block>
</results>
于 2012-05-31T07:24:00.830 回答
0

这个样式表...

<xsl:stylesheet
  version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xsl:output method="xml" indent="yes" encoding="utf-8" />
<xsl:strip-space elements="text"/>
<xsl:key name="text-resource" match="line" use="normalize-space(@id)" />
<xsl:key name="image-resource" match="image" use="normalize-space(@id)" />

<xsl:template match="/">
 <result>
  <xsl:apply-templates select="analysis/blocks/block" />
 </result>
</xsl:template>

<xsl:template match="block">
  <block id="{@id}">
  <xsl:variable name="block" select="." />

  <xsl:variable name="block-texts" as="xs:string+">
    <xsl:for-each select="tokenize(contain/text(),'\s?,\s?')" >
     <xsl:variable name="id" select="." />
     <xsl:for-each select="$block" >
      <xsl:sequence select="key('text-resource',$id)/following-sibling::char[preceding-sibling::line[1][@id=$id]]" />
     </xsl:for-each>
    </xsl:for-each>
  </xsl:variable>

  <xsl:if test="count( $block-texts) != 0" >
   <text>
    <xsl:for-each select="$block-texts" >
     <xsl:value-of select="." />
    </xsl:for-each>
   </text>
  </xsl:if>

    <xsl:for-each select="tokenize(contain/text(),'\s?,\s?')" >
     <xsl:variable name="id" select="." />
     <xsl:for-each select="$block" >
      <xsl:for-each select="key('image-resource',$id)" >
       <image href="{.}" />
      </xsl:for-each>
      </xsl:for-each>
     </xsl:for-each>
  </block>
</xsl:template>

</xsl:stylesheet>

...当应用于问题中给出的输入文档时,产生...

<?xml version="1.0" encoding="utf-8"?>
<result xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <block id="35">
      <text>aaaabbbb</text>
   </block>
   <block id="33">
      <text>ccccddddeeee</text>
      <image href="./img/a.jpg "/>
   </block>
</result>

我希望你能找到我最接近的解决方案。

于 2012-05-31T09:58:11.730 回答