【问题标题】:XQuery Recursive Function Call for Inner Tag内部标记的 XQuery 递归函数调用
【发布时间】:2015-01-11 18:41:46
【问题描述】:

我正在尝试准备一个 XML 文件来解析它的 JSON,它的上下文是这样的:

<user_manual>
  <embed-language_part id="SL14686180">
    <language_part id="1" role="-" lang="de">
      <embed-user_manual_part id="1">
        <user_manual_part id="1" role="-" document-type="IU">
          <embed-chapter id="1">
            <?ecls-start-embedded-resource resource="ecls_bio_becls_a3_a30660983"?>
            <chapter id="1" role="-" toctitle="yes" footrowtitle="no" type="security">
              <embed-title_module id="1">
                <title_module id="1" role="-">
                  <title id="1">Sicherheits- und Warnhinweise</title>
                </title_module>
              </embed-title_module>
              <embed-section id="1">
                <section id="1" footrowtitle="no" role="-" toctitle="yes">
                  <embed-section id="2">
                    <section id="2">
                      <embed-title_module id="2">
                        <title_module id="2" role="-">
                          <title id="2">Eisschale</title>
                        </title_module>
                      </embed-title_module>
                    </section>
                  </embed-section>
                  <embed-title_module id="3">
                    <title_module id="31" role="-">
                      <title id="3">Bevor Sie das Gerat in Betrieb nehmen</title>
                    </title_module>
                  </embed-title_module>
                </section>
              </embed-section>
            </chapter>
          </embed-chapter>
        </user_manual_part>
      </embed-user_manual_part>
    </language_part>
  </embed-language_part>
</user_manual>

我首先根据我的期望编写了一个 XQuery 脚本(假设 $doc 是文档,$matnr 是 22333),

declare variable $doc external;
declare variable $matnr external;
<dmContainer>{
for $language in $doc/user_manual/embed-language_part/language_part
let $lang_code := data($language/@lang)
for $embed_chapter in $language/embed-user_manual_part/user_manual_part/embed-chapter
let $objectid := data($embed_chapter/processing-instruction('ecls-start-embedded-resource'))[1]  
let $fileattr := string($objectid)
let $filename := translate(substring-after($objectid,'resource='),'&quot;','')
let $postfix :=  substring(tokenize($filename,'_')[last()], 2)    

let $name := concat($matnr, '_', $postfix)                              
 return (element {$lang_code} {    
    attribute title {data($embed_chapter/chapter/embed-title_module/title_module/title)},
    attribute language {$lang_code},   
    attribute name {$name},        
    for $section in $embed_chapter/chapter/embed-section/section
        return <section title="{data($section/embed-title_module/title_module/title)}"></section>
})
}</dmContainer>

这会返回:

<dmContainer>
   <de title="Sicherheits- und Warnhinweise" language="de" name="223333_30660983">
      <section title="Bevor Sie das Gerat in Betrieb nehmen" />
   </de>
</dmContainer>

返回包含 JSON 的章节元素及其第一部分的标题,但我必须将这个添加到所有部分(部分也包含部分)。

根据输入的 XML,这些部分可以递归地包含另一个部分(一个或多个)。您可以通过深入搜索来查看示例。问题是我如何使用适当的递归方式将这些部分添加到我的输出中(我的意思不仅包括一级二级子级的子级),我搜索了 XQuery 的一些示例递归函数,但我无法得到任何人。

预期输出:

 <dmContainer>
   <de title="Sicherheits- und Warnhinweise" language="de" name="223333_30660983">
      <section title="Bevor Sie das Gerat in Betrieb nehmen">
      <section title="Eisschale"/>
      </section>
   </de>
</dmContainer>

如何获取所有部分?

【问题讨论】:

  • 请查看如何发布SSCCE。如果您希望其他人专门针对您的代码回答您的问题,请确保他们可以通过复制粘贴直接运行代码:没有外部变量,$language 是什么?对 XML 进行一些适当的缩进也有助于理解问题。
  • 我在问题上写了$doc是文档名,$matnr是22333。其他的都是从$doc派生的,$language也是派生的。那么问题出在哪里?
  • 看来我没能把所有东西放在一起,你是对的。我删除了我的反对票,因为代码经过一些修改后可以工作。不过,我仍然不认为这是一个的问题。为什么要声明外部变量,而不是把内容放在那里?无需描述传递给它们的内容(而且这个描述并不正确:似乎$doc 不应该包含“文档名称”,而是文档)。这是一个展示努力的问题,也去掉了不必要的部分(比如语言和名称属性的整个结构,这与问题无关。
  • 对不起,我在这件事上犯了错误,感谢您的编辑。

标签: recursion xquery


【解决方案1】:

如果您只想要该章中的所有部分(按文档顺序),请使用descendant-or-self-step,缩写为//

for $section in $embed_chapter/chapter//embed-section/section
    return <section title="{data($section/embed-title_module/title_module/title)}"

如果文档顺序不适合您(例如,首先是当前部分的标题,然后是当前级别的所有子部分,无论它们是否实际位于标题之前),您必须自己编写遍历树的函数:获取当前节、返回标题并递归调用自身以获取直接子节(如果有的话)的函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 2015-05-09
    相关资源
    最近更新 更多