首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >xml -导管解析xml属性。

xml -导管解析xml属性。
EN

Stack Overflow用户
提问于 2015-12-14 12:06:36
回答 1查看 194关注 0票数 0

使用xml-conduit解析XML时,我偶然发现了以下问题:当我有多个属性时,具有相同的基名,但前缀不同,只按(词法)顺序排列。

如果同时存在一个属性的前缀版本和非前缀版本,那么如何获得前缀值?

最小非工作示例:

Main.hs

代码语言:javascript
复制
{-# LANGUAGE OverloadedStrings #-}

module Main where

import           Data.Text.Lazy (Text)
import qualified Data.Text.Lazy as T
import           Text.XML (parseText, def, elementAttributes, documentRoot)
import           Data.List (splitAt, drop)

main :: IO ()
main = do
  putStrLn "Example1: only the first element is parsed"
  putStrLn "========\n"
  print $ elementAttributes . documentRoot <$> parseText def (T.unlines test)
  putStrLn "Example2: this behaviour is independent of both having a prefix"
  putStrLn "========\n"
  print $ elementAttributes . documentRoot <$> parseText def (T.unlines $ dropAt 1 test)
  putStrLn "Example3: also no difference if there is just one attribute with prefix"
  putStrLn "========\n"
  print $ elementAttributes . documentRoot <$> parseText def (T.unlines $ dropAt 2 test)
  putStrLn "Example4: on its own the last element can be parsed"
  putStrLn "========\n"
  print $ elementAttributes . documentRoot <$> parseText def (T.unlines $ dropAt 1 $ dropAt 1 test)
  putStrLn "==============="
  putStrLn "Example1: it is always the first element parsed"
  putStrLn "========\n"
  print $ elementAttributes . documentRoot <$> parseText def (T.unlines test2)
  putStrLn "Example2: really just the first"
  putStrLn "========\n"
  print $ elementAttributes . documentRoot <$> parseText def (T.unlines $ dropAt 1 test2)


test :: [Text]
test =["<Root"
      ,  "here    = \"ok\""
      ,  "is:here = \"ok\""
      ,  "not:here=\"nok\">"
      ,"</Root>"]

test2 :: [Text]
test2 =["<Root"
       ,  "is:here = \"ok\""
       ,  "here    = \"ok\""
       ,  "not:here=\"nok\">"
       ,"</Root>"]

dropAt :: Int -> [a] -> [a]
dropAt i xs = let (hd,tl) = splitAt i xs
              in hd ++ drop 1 tl

attr.cabal

代码语言:javascript
复制
build-depends: base >= 4.7 && < 5
             , xml-conduit
             , text

> stack exec attr
Example1: only the first element is parsed
========

Right (fromList [(Name {nameLocalName = "here", nameNamespace = Nothing, namePrefix = Nothing},"ok")])
Example2: this behaviour is independent of both having a prefix
========

Right (fromList [(Name {nameLocalName = "here", nameNamespace = Nothing, namePrefix = Just "is"},"ok")])
Example3: also no difference if there is just one attribute with prefix
========

Right (fromList [(Name {nameLocalName = "here", nameNamespace = Nothing, namePrefix = Nothing},"ok")])
Example4: on its own the last element can be parsed
========

Right (fromList [(Name {nameLocalName = "here", nameNamespace = Nothing, namePrefix = Just "not"},"nok")])
===============
Example1: only the first element is parsed
========

Right (fromList [(Name {nameLocalName = "here", nameNamespace = Nothing, namePrefix = Just "is"},"ok")])
Example2: this behaviour is independent of both having a prefix
========

Right (fromList [(Name {nameLocalName = "here", nameNamespace = Nothing, namePrefix = Nothing},"ok")])
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-15 01:01:30

引用Text.XML.Name

前缀在语义上并不重要;它们被包括进来只是为了简化传递解析。当将名称与Eq或Ord方法进行比较时,前缀将被忽略。

语义差异在于名称空间,因此以下内容解决了您的问题:

代码语言:javascript
复制
test :: [Text]
test =["<Root xmlns:is=\"http://example.com\" xmlns:not=\"http://example.com/2\""
      ,  "here    = \"ok\""
      ,  "is:here = \"ok\""
      ,  "not:here=\"nok\">"
      ,"</Root>"]

这也是有意义的,因为我们可以在不同的地方不同地命名相同的名称空间,但应该是相同的。我认为,如果不将名称空间与前缀相关联,那么使用前缀也是无效的XML。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34266662

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档