如何使用Scala XML返回空节点?

时间:2016-04-27 16:55:36

标签: xml scala

请注意,此问题与返回0或1个元素(Node或Elem)严格相关。请不要将NodeSeq.Empty视为一种解决方案,因为这已经适用于返回NodeSeq类型(0个或更多元素)的函数,已在this question上解决。

我正在使用不同的函数构建XML,例如以下示例:

const char **fnames;       /* pointers to field names */
const mwSize *dims;
mxArray    *tmp, *fout;
char       *pdata=NULL;
int        ifield, nfields;
mxClassID  *classIDflags;
mwIndex    jstruct;
mwSize     NStructElems;
mwSize     ndim;

/* allocate memory  for storing pointers */
fnames = mxCalloc(nfields, sizeof(*fnames));
/* get field name pointers */
for (ifield=0; ifield< nfields; ifield++){
    fnames[ifield] = mxGetFieldNameByNumber(prhs[0],ifield);
}
/* create a 1x1 struct matrix for output  */
plhs[0] = mxCreateStructMatrix(1, 1, nfields, fnames);
mxFree((void *)fnames);
ndim = mxGetNumberOfDimensions(prhs[0]);
dims = mxGetDimensions(prhs[0]);
for(ifield=0; ifield<nfields; ifield++) {
    /* create cell/numeric array */
    if(classIDflags[ifield] == mxCHAR_CLASS) {
        fout = mxCreateCellArray(ndim, dims);
    }else {
        fout = mxCreateNumericArray(ndim, dims, classIDflags[ifield], mxREAL);
        pdata = mxGetData(fout);
    }
    /* copy data from input structure array */
    for (jstruct=0; jstruct<NStructElems; jstruct++) {
        tmp = mxGetFieldByNumber(prhs[0],jstruct,ifield);
        if( mxIsChar(tmp)) {
            mxSetCell(fout, jstruct, mxDuplicateArray(tmp));
        }else {
            mwSize     sizebuf;
            sizebuf = mxGetElementSize(tmp);
            memcpy(pdata, mxGetData(tmp), sizebuf);
            pdata += sizebuf;
        }
    }
    /* set each field in output structure */
    mxSetFieldByNumber(plhs[0], 0, ifield, fout);
}
mxFree(classIDflags);

尝试根据param的值返回Empty或非空节点(或Elem),例如:

<xml>
  { maybeXmlNode(param) }
</xml>

我现在使用的解决方案是将函数类型定义为Option [Elem],然后将其用作maybeXml.getOrElse(“”),但这对我来说没那么有意义。我目前的用法如下:

def maybeXmlNode(param: Boolean): NodeOrElem = {
  if(param) <someXml></someXml>
  else ??? //Empty or None doesn't work
}

是否存在更好的表达方式,可能直接使用空节点或Elem?

2 个答案:

答案 0 :(得分:0)

尝试

<xml>{maybeXmlNode(param).getOrElse(new NodeBuffer())}</xml>

答案 1 :(得分:0)

我一直在寻找相同的东西(几年后)。似乎不存在真正的解决方案。
但是我用xml.Text("")来解决它(Unparsed("")很相似,但是漂亮的打印有时很有趣)。

示例:

val pretty = new PrettyPrinter(100, 2)
println(pretty.format(
  <elem attrib={Text("")}>
    {Text("")}
    <withtag thing="thang">
      boop
    </withtag>
    {"something"}
  </elem>
))

输出

<elem attrib="">
  <withtag thing="thang"> boop </withtag>
  something
</elem>

但是,这可能会导致类似行为的明显行为

def wrap(node: Node) = <wrapped>{node}</wrapped>

(很难判断是否应该期待另一个“空”节点,或者没有子元素的包装元素)。它也不适用于xml.Utility.trim