代码之家  ›  专栏  ›  技术社区  ›  Lena S

将一个xml文件中的值合并到另一个xml文件中。

  •  0
  • Lena S  · 技术社区  · 6 年前

    我有以下xml文件(我们称它们为paragraph.xml和sencement.xml)。

    段落.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <paragraphs>
         <paragraph id="par_1" parBegin="1" parEnd="100" par_type="intro" context="positive"/>
         <paragraph id="par_2" parBegin="101" parEnd="170" par_type="elaboration" context="negative"/>
         <paragraph id="par_3" parBegin="171" parEnd="210" par_type="elaboration" context="positive"/>
         <paragraph id="par_4" parBegin="211" parEnd="280" par_type="conclusion" context="neutral"/>
    

    帕尔贝京 “显示段落开头的字号和” “显示段落结束处的字数。例如,第一个段落元素以word开头 1 (parBegin属性的值)并以word结尾

    另一个xml文件 句子.xml 有关于同一课文句子的信息。

    <?xml version="1.0" encoding="UTF-8"?>
     <sentences>
         <sentence id="sent_1" sentBegin="1" sentEnd="15" sent_type="question"/>
         <sentence id="sent_2" sentBegin="16" sentEnd="30" sent_type="imperative"/>
         <sentence id="sent_3" sentBegin="31" sentEnd="37" sent_type="confirmation"/>
         ...
         <sentence id="sent_15" sentBegin="120" sentEnd="125" sent_type="conclusion" />
    

    “显示句子开头的字号和” 森坦德 “显示段落结束处的字数。例如,第一个句子元素以单词开头 1 15 id=“已发送\u 15” 以单词120开头(sentEnd=“120”),以单词125结尾(sentEnd=“125”)。

    我想做的是检查每个句子属于哪一段。 换句话说,比较属性的值 @森坦德 属性的值 @帕伦德 . 如果 大于 @帕尔贝京 小于 在段落元素中,表示该句子属于该段落。例如,句子的sentEnd值(id=“sent\u 15”)是125( sentEnd=“125” )它比 @帕尔贝京 id=“第2部分” @帕伦德 (parEnd=“170”)值。这说明这句话 id=“已发送\u 15” 属于段落 id=“第2部分” . 所需的输出如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
     <sentences>
         <sentence id="sent_1" sentBegin="1" sentEnd="15" sent_type="question" paragraph="par_1" par_type="intro"/>
         <sentence id="sent_2" sentBegin="16" sentEnd="30" sent_type="imperative" paragraph="par_1" par_type="intro"/>
         <sentence id="sent_3" sentBegin="31" sentEnd="37" sent_type="confirmation" paragraph="par_1" par_type="intro"/>
         ...
         <sentence id="sent_15" sentBegin="120" sentEnd="125" sent_type="conclusion" paragraph="par_2" par_type="elaboration" />
    

    非常感谢您的反馈/解决方案。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Martin Honnen    6 年前

    看起来你只要选对就行了 paragraph

      <xsl:template match="sentence">
          <xsl:copy>
              <xsl:apply-templates 
                 select="@*, 
                         $paragraph-doc/paragraphs/paragraph[xs:integer(@parBegin) &lt;= xs:integer(current()/@sentBegin) and xs:integer(@parEnd) >= xs:integer(current()/@sentEnd)]/(@id, @par_type)"/>
          </xsl:copy>
      </xsl:template>
    

    在下面,我将段落文档内联到一个参数中,但是您当然可以使用 doc 功能:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="#all"
        version="3.0">
    
      <xsl:param name="paragraph-doc">
        <paragraphs>
             <paragraph id="par_1" parBegin="1" parEnd="100" par_type="intro" context="positive"/>
             <paragraph id="par_2" parBegin="101" parEnd="170" par_type="elaboration" context="negative"/>
             <paragraph id="par_3" parBegin="171" parEnd="210" par_type="elaboration" context="positive"/>
             <paragraph id="par_4" parBegin="211" parEnd="280" par_type="conclusion" context="neutral"/>
        </paragraphs>
      </xsl:param>
    
      <xsl:mode on-no-match="shallow-copy"/>
    
      <xsl:template match="sentence">
          <xsl:copy>
              <xsl:apply-templates 
                 select="@*, 
                         $paragraph-doc/paragraphs/paragraph[xs:integer(@parBegin) &lt;= xs:integer(current()/@sentBegin) and xs:integer(@parEnd) >= xs:integer(current()/@sentEnd)]/(@id, @par_type)"/>
          </xsl:copy>
      </xsl:template>
    
      <xsl:template match="paragraph/@id">
          <xsl:attribute name="paragraph" select="."/>
      </xsl:template>
    
    </xsl:stylesheet>
    

    https://xsltfiddle.liberty-development.net/nc4NzQZ 是XSLT 3示例,对于XSLT 2,您需要替换使用的 xsl:mode

    作为上述的改进或替代,我们可以 上的元素 @parBegin to @parEnd

    <?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="#all"
        version="3.0">
    
      <xsl:param name="paragraph-doc">
        <paragraphs>
             <paragraph id="par_1" parBegin="1" parEnd="100" par_type="intro" context="positive"/>
             <paragraph id="par_2" parBegin="101" parEnd="170" par_type="elaboration" context="negative"/>
             <paragraph id="par_3" parBegin="171" parEnd="210" par_type="elaboration" context="positive"/>
             <paragraph id="par_4" parBegin="211" parEnd="280" par_type="conclusion" context="neutral"/>
        </paragraphs>
      </xsl:param>
    
      <xsl:key name="par-ref" match="paragraph" use="@parBegin to @parEnd"/>
    
      <xsl:mode on-no-match="shallow-copy"/>
    
      <xsl:template match="sentence">
          <xsl:copy>
              <xsl:apply-templates 
                 select="@*, 
                         key('par-ref', xs:integer(@sentEnd), $paragraph-doc)/(@id, @par_type)"/>
          </xsl:copy>
      </xsl:template>
    
      <xsl:template match="paragraph/@id">
          <xsl:attribute name="paragraph" select="."/>
      </xsl:template>
    
    </xsl:stylesheet>
    

    https://xsltfiddle.liberty-development.net/nc4NzQZ/2