【问题标题】:incorporate values from one xml file into another.将一个 xml 文件中的值合并到另一个文件中。
【发布时间】:2019-03-05 19:37:05
【问题描述】:

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

Paragraph.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"/>

在paragraph.xml文件中,属性“parBegin”显示段落开始的字数,“parEnd”显示段落所在的字数结束。例如,第一个段落元素以单词 1(parBegin 属性的值)开头,以单词 100 结尾(第一段有 100 个单词)。

另一个 xml 文件 sentence.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" />

在sentence.xml文件中,属性“sentBegin”显示句子开始的单词编号,“sentEnd”显示段落所在单词的编号结束。例如,第一个句子元素以单词 1(sentBegin 属性的值)开头,以单词 15 结尾。 id="sent_15" 的句子以单词 120 (sentBegin="120") 开始,以单词 125 (sentEnd="125") 结束。

我要做的是检查每个句子属于哪个段落。换句话说,将属性@sentEnd的值与属性 @parEnd。如果一个段落元素的@sentEnd大于@parBegin且小于@parEnd,则表明该句子属于该段落。例如,句子 (id="sent_15") 的 sentEnd 值为 125 (sentEnd="125"),大于 @parBegin (parBegin= id="par_2" 且小于其 @parEnd (parEnd="170") 值的段落的 "101") 值。这表明句子 id="sent_15" 属于段落 id="par_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" />

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

【问题讨论】:

    标签: xml xslt attributes xslt-2.0 transformation


    【解决方案1】:

    看起来您可以使用谓词简单地选择正确的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 上键入paragraph 元素,然后使用该键从句子中查找相关段落:

    <?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

    【讨论】:

      猜你喜欢
      • 2012-08-16
      • 1970-01-01
      • 2012-07-08
      • 2016-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多