简体   繁体   中英

Generating TAB-delimited records of key-value pairs from XML with pure XPath 3

From this XML:

<root>
    <item>
        <a>i1.a1</a>
        <b>i1.b1</b>
    </item>
    <item>
        <b>i2.b1</b>
        <c>i2.c1</c>
    </item>
    <item>
        <a>i3.a1</a>
        <a>i3.a2</a>
    </item>
</root>

With pure XPath, I would like to generate:

a=i1.a1 b=i1.b1
b=i2.b1 c=i2.c1
a=i3.a1 a=i3.a2

Here's my approach:

//item/string-join(
    for $name in distinct-values( */name() )
    return concat(
        $name,
        "=",
        string( *[name()=$name][last()]/text() ) 
    ),
    codepoints-to-string(9)
)

Which generates:

a=i1.a1 b=i1.b1
b=i2.b1 c=i2.c1
a=i3.a2

How could I handle the duplicate tags correctly?

I like to use for... in... return for tasks like this, for clarity:

string-join(
   for 
      $item in /root/item 
   return
      string-join(
         for 
            $value in $item/* 
         return
            local-name($value) || '=' || $value,
         codepoints-to-string(9)
      ),
   codepoints-to-string(10)
)

I haven't actually tested this, but I think it's right

Try

//item ! string-join(* ! (name() || '=' || .),
    codepoints-to-string(9)
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM