Xquery 什么&x201C;属性节点不能跟随元素内容中的非属性节点”;告诉我

Xquery 什么&x201C;属性节点不能跟随元素内容中的非属性节点”;告诉我,xquery,xslt-2.0,Xquery,Xslt 2.0,one attr.xml 我使用XQuery将id属性转换为元素。在70K个文档中只有两个文档,如two attr.xml。 显然,currency元素已经具有值USD。在转换两个attr.xml时,我在ML QConsole中发现以下错误。我在氧气方面也有类似的错误 我的XQuery模块: 集体成功的底层转换是针对one attr.xml模型的。Java | ML API、Oxygen、XSLT返回相同的结果: ,我希望以下结果能够帮助搜索引擎: <executionReport xml

one attr.xml

我使用XQuery将
id
属性转换为元素。在70K个文档中只有两个文档,如
two attr.xml
。 显然,
currency
元素已经具有值
USD
。在转换
两个attr.xml
时,我在ML QConsole中发现以下错误。我在氧气方面也有类似的错误

我的XQuery模块:

集体成功的底层转换是针对
one attr.xml
模型的。Java | ML API、Oxygen、XSLT返回相同的结果:

,我希望以下结果能够帮助搜索引擎:

<executionReport xmlns="schema://fc.fasset/execution">
    <trade>
    <cal>
        <c>PRECEDING</c>
        <bcs>
            <id>businessCenters</id>
            <bc>USNY</bc>
            <bc>GBLO</bc>
        </bcs>
    </cal>
    <amount>
        <currency>USD</currency>        
        <id>settlementCurrency</id>
        <referenceAmount>StandardISDA</referenceAmount>
        <cashSettlement>true</cashSettlement>
    </amount>
    </trade>
</executionReport>

之前的
商业中心
松软的
GBLO
美元
结算货币
标准协会
真的
在以下解决方案中,最新结果如下:


之前的
松软的
GBLO
商业中心
美元
结算货币
标准协会
真的
如何让我的XQuery和XSLT模块工作


开始创建子节点后,无法创建属性。因此,如果要将
@id
转换为
,则必须在复制其他属性后进行转换

避免此问题的最短、最简单的方法是对属性进行排序,确保先处理将要向前复制的属性,然后处理将转换为元素的属性

通过对从
hof:remove-attr-except()
函数返回的项目序列进行排序,确保序列具有属性,然后是元素:

element { fn:QName ($newNs, local-name($node)) }
  { for $item in (hof:remove-attr-except($node, $newNs, $keepAttr))
    order by $item instance of attribute() descending
    return $item }
declare function hof:remove-attr-except
  ( $node as node()* ,
    $newNs as xs:string ,
    $keepAttr as xs:string* 
  ) as node()* 
  {
    for $attr in $node/@*
    where not(local-name($attr) = $keepAttr)
    return
      $node/@*[name() = $keepAttr], hof:transform-ns-root-flatten($node/node(), $newNs, $keepAttr)
    ,  
    for $attr in $node/@*
    where local-name($attr) = $keepAttr
    return 
     element {fn:QName ($newNs, name($attr))} {data($attr)}    
  };
您还可以有两个单独的FLWOR,其中包含一个
where
子句,该子句处理
$keepAttr
,然后将其转换为元素:

element { fn:QName ($newNs, local-name($node)) }
  { for $item in (hof:remove-attr-except($node, $newNs, $keepAttr))
    order by $item instance of attribute() descending
    return $item }
declare function hof:remove-attr-except
  ( $node as node()* ,
    $newNs as xs:string ,
    $keepAttr as xs:string* 
  ) as node()* 
  {
    for $attr in $node/@*
    where not(local-name($attr) = $keepAttr)
    return
      $node/@*[name() = $keepAttr], hof:transform-ns-root-flatten($node/node(), $newNs, $keepAttr)
    ,  
    for $attr in $node/@*
    where local-name($attr) = $keepAttr
    return 
     element {fn:QName ($newNs, name($attr))} {data($attr)}    
  };
但是,如果您希望这些新元素位于原始元素之外,并且不希望保留属性,那么我将更改
类型开关
中元素的处理,以便调用将这些属性转换为元素构造函数之外的元素的函数:

declare namespace hof = "http://fc.fasset/function";

declare function hof:attr-to-element
  ( $node as node()* ,
    $newNs as xs:string ,
    $keepAttr as xs:string* 
  ) as node()* 
  {  
    for $attr in $node/@*
    where local-name($attr) = $keepAttr
    return 
     element {fn:QName ($newNs, name($attr))} {data($attr)}    
  };  
  
declare function hof:transform-ns-root-flatten
  ( $nodes as node()* ,
    $newNs as xs:string ,
    $keepAttr as xs:string*
  ) as node()* 
  {
    for $node in $nodes
    return 
        typeswitch($node)
            case $node as element()
                return (element { fn:QName ($newNs, local-name($node)) }
                            { hof:transform-ns-root-flatten($node/node(), $newNs, $keepAttr)  }
                        ,
                        hof:attr-to-element($node, $newNs, $keepAttr)
                       )
            case $node as document-node()
                return hof:transform-ns-root-flatten($node/node(), $newNs, fn:normalize-space($keepAttr))          
    default return $node 
  };
上面的代码从提供的输入XML生成以下输出:

<executionReport xmlns="schema://fc.fasset/execution">
  <amount>
    <currency>USD</currency>
    <id>settlementCurrency</id>
    <referenceAmount>StandardISDA</referenceAmount>
    <cashSettlement>true</cashSettlement>
  </amount>
</executionReport>

美元
结算货币
标准协会
真的

请包含更多失败的XQuery脚本。您的XML可能看起来不寻常,但格式良好。元素的内容可以包含任何顺序的文本节点和元素节点。当然,它是可以搜索的,尽管有点困难。但作为一种良好实践,混合内容(文本节点作为元素节点的兄弟节点)最好保留用于文本标记,例如,在句子中标记斜体文字。一定是男性和女性大脑之间的裂痕:请详细说明在X世界中,在句子中标记斜体文字。…注意,尽管从执行顺序的角度考虑这一点很方便(“你不能在做Y之后做X”)形式定义是,在用于形成元素内容的项目序列中,属性节点必须位于子节点之前。谢谢Mads!1) 你能解释一下你的第一段代码的位置吗?我的结果是
结算货币USD
2)您的
hof:attr to element
解决方案返回
USD结算货币
我想还有一个调用来删除缺少的attr(
id
)吗?但我还没有弄明白如何递归调用函数来维护|删除属性。。。第一个代码示例(对结果进行排序,但保留现有逻辑)简单地避免了错误。如果您不喜欢输出,并且确实希望将元素移到currency元素之外,那么最后一个代码块就是您想要的。但是,您的示例没有显示输出中保留的其他属性。要保留它们吗?请注意,在我的上一个示例中,
hof:attr-to-element()
在元素构造函数外部调用。它是
元素()
大小写表达式序列中的第二项
<executionReport xmlns="schema://fc.fasset/execution">
    <trade>
    <cal>
        <c>PRECEDING</c>
        <bcs>
            <id>businessCenters</id>
            <bc>USNY</bc>
            <bc>GBLO</bc>
        </bcs>
    </cal>
    <amount>
        <currency>USD</currency>        
        <id>settlementCurrency</id>
        <referenceAmount>StandardISDA</referenceAmount>
        <cashSettlement>true</cashSettlement>
    </amount>
    </trade>
</executionReport>
<executionReport xmlns="schema://fc.fasset/execution">
    <cal>
        <c>PRECEDING</c>
        <bcs>
            <bc>USNY</bc>
            <bc>GBLO</bc>
        </bcs>
<!-- Line9: id is out of <bcs> element and its context is completed lost!  -->
        <id>businessCenters</id>
    </cal>
    <amount>
        <currency>USD</currency>
<!-- Line14: id is in the correct position! -->
        <id>settlementCurrency</id>
        <referenceAmount>StandardISDA</referenceAmount>
        <cashSettlement>true</cashSettlement>
    </amount>
</executionReport>
element { fn:QName ($newNs, local-name($node)) }
  { for $item in (hof:remove-attr-except($node, $newNs, $keepAttr))
    order by $item instance of attribute() descending
    return $item }
declare function hof:remove-attr-except
  ( $node as node()* ,
    $newNs as xs:string ,
    $keepAttr as xs:string* 
  ) as node()* 
  {
    for $attr in $node/@*
    where not(local-name($attr) = $keepAttr)
    return
      $node/@*[name() = $keepAttr], hof:transform-ns-root-flatten($node/node(), $newNs, $keepAttr)
    ,  
    for $attr in $node/@*
    where local-name($attr) = $keepAttr
    return 
     element {fn:QName ($newNs, name($attr))} {data($attr)}    
  };
declare namespace hof = "http://fc.fasset/function";

declare function hof:attr-to-element
  ( $node as node()* ,
    $newNs as xs:string ,
    $keepAttr as xs:string* 
  ) as node()* 
  {  
    for $attr in $node/@*
    where local-name($attr) = $keepAttr
    return 
     element {fn:QName ($newNs, name($attr))} {data($attr)}    
  };  
  
declare function hof:transform-ns-root-flatten
  ( $nodes as node()* ,
    $newNs as xs:string ,
    $keepAttr as xs:string*
  ) as node()* 
  {
    for $node in $nodes
    return 
        typeswitch($node)
            case $node as element()
                return (element { fn:QName ($newNs, local-name($node)) }
                            { hof:transform-ns-root-flatten($node/node(), $newNs, $keepAttr)  }
                        ,
                        hof:attr-to-element($node, $newNs, $keepAttr)
                       )
            case $node as document-node()
                return hof:transform-ns-root-flatten($node/node(), $newNs, fn:normalize-space($keepAttr))          
    default return $node 
  };
<executionReport xmlns="schema://fc.fasset/execution">
  <amount>
    <currency>USD</currency>
    <id>settlementCurrency</id>
    <referenceAmount>StandardISDA</referenceAmount>
    <cashSettlement>true</cashSettlement>
  </amount>
</executionReport>