使用<节>>的数目,用HXT转换节点。祖先节点 [英] Transform nodes with HXT using the number of <section> ancestor nodes

查看:173
本文介绍了使用<节>>的数目,用HXT转换节点。祖先节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 h1 h2来替换所有 title code>,..., h6 元素,具体取决于有多少祖先是部分元素。示例输入/输出:

Input.xml

 <文件> 
<节>
< title>标题A< / title>
<节>
< title>标题B< / title>
< / section>
<节>
< title>标题C< / title>
<节>
< title>标题D< / title>
< / section>
< / section>
< / section>
< / document>

Output.xml

 < document> 
<节>
< h1>标题A< / h1>
<节>
< h2>标题B< / h2>
< / section>
<节>
< h2>标题C< / h2>
<节>
< h3>标题D< / h3>
< / section>
< / section>
< / section>
< / document>

我可以将所有 title code> h1 s使用类似的东西

  swapTitles :: ArrowXml a =>一个XmlTree XmlTree 
swapTitles = processTopDown $
(changeQName。const $ mkNameh1)
`when`
(isElem>>>(hasQName $ mkNametitle ))

我相信我应该使用ArrowState,但我一直无法弄清楚怎么样。有人可以指点我吗?

使用 XSL ,包 hxt-xslt <一>。标准让生活更轻松: - )
$ b

  { - #LANGUAGE箭头,PackageImports# - } 

导入System.Environment(getArgs)
导入System.Exit(exitSuccess,exitWith,ExitCode(..))

导入Control.Arrow
导入 hxtText.XML.HXT.Core
importhxtText.XML.HXT.DOM.XmlKeywords
importhxt-xsltText.XML.HXT.XSLT.XsltArrows
import hxtText.XML.HXT.Arrow.XmlState.TraceHandling(withTraceLevel)

process :: String - >字符串 - > IO [String]
process xslStylesheetPath xmlDocPath = do

- 编译样式表
$ b compiledStyleSheetResults< - runX $
arr(const xslStylesheetPath)
>>> readXSLTDoc [withValidate yes,withInputEncoding utf8] - withTrace 2
>>> { - withTraceLevel 2 - } xsltCompileStylesheet

case
[] - >的compiledStyleSheetResults return [错误编译++ xslStylesheetPath]
compiledStyleSheet:_ - > do

- 将编译的样式表应用于xml文档

runX $ arr(const xmlDocPath)
>>> readXSLTDoc [withValidate yes,withInputEncoding utf8] - withTrace 2
>>> xsltApplyStylesheet compiledStyleSheet
>>> writeDocumentToString [withOutputEncoding utf8,
withXmlPi yes,withIndent yes]

- 模块内部的readXSLTDoc Text.XML.HXT.XSLT.XsltArrows

readXSLTDoc :: SysConfigList - > IOSArrow字符串XmlTree
readXSLTDoc选项
= readFromDocument(options ++ defaultOptions)
其中
defaultOptions
= [withCheckNamespaces yes
,withValidate no
,withPreserveComment no
]

main = do
args< - getArgs

[arg1,arg2] - >做
结果< - 进程arg1 arg2
结果
[] - > putStrLn错误
结果:_ - > putStrLn结果

exitSuccess

_ - >做
putStrLn缺少参数:xslStylesheetPath xmlDocPath
exitWith $ ExitFailure 1

使用XSL文件mystyle.xsl

 <?xml version =1.0encoding = UTF-8 >?; 
< xsl:stylesheet version =1.0xmlns:xsl =http://www.w3.org/1999/XSL/Transform>

< xsl:template match =/>
< xsl:for-each select =document>
< xsl:copy>
< xsl:call-template name =myloop>
< xsl:with-param name =nestingselect =0/>
< / xsl:call-template>
< / xsl:copy>
< / xsl:for-each>
< / xsl:template>

< xsl:template name =myloop>
< xsl:param name =nesting/>

< xsl:if test =title>
< xsl:value-of select =title/>
< / xsl:element>
< / xsl:if>

< xsl:for-each select =section>
< xsl:copy>
< xsl:call-template name =myloop>
< / xsl:call-template>
< / xsl:copy>
< / xsl:for-each>

< / xsl:template>
< / xsl:stylesheet>

加上yourdata.xml

 <?xml version =1.0encoding =UTF-8?> 
<文件>
<节>
< title>标题A< / title>
<节>
< title>标题B< / title>
< / section>
<节>
< title>标题C< / title>
<节>
< title>标题D< / title>
< / section>
< / section>
< / section>
< / document>

跑步

  runhaskell test.hs mystyle.xsl yourdata.xml 

结果:
$ b

 <?xml version =1.0encoding =UTF-8? > 
<文件>
<节>
< h1>标题A< / h1>
<节>
< h2>标题B< / h2>
< / section>
<节>
< h2>标题C< / h2>
<节>
< h3>标题D< / h3>
< / section>
< / section>
< / section>
< / document>


I'm looking to replace all title elements with h1, h2, ... , h6 elements depending on how many ancestors are section elements. Example input/output:

Input.xml

<document>
    <section>
        <title>Title A</title>
        <section>
            <title>Title B</title>
        </section>
        <section>
            <title>Title C</title>
            <section>
                <title>Title D</title>
            </section>
        </section>
    </section>
</document>

Output.xml

<document>
    <section>
        <h1>Title A</h1>
        <section>
            <h2>Title B</h2>
        </section>
        <section>
            <h2>Title C</h2>
            <section>
                <h3>Title D</h3>
            </section>
        </section>
    </section>
</document>

I can replace all titles with h1s using something like this

swapTitles :: ArrowXml a => a XmlTree XmlTree
swapTitles = processTopDown $
             (changeQName . const $ mkName "h1")
             `when`
             (isElem >>> (hasQName $ mkName "title"))

I believe I should be using ArrowState, but I've not been able to figure out how. Can someone point me in the right direction?

解决方案

Using XSL with package hxt-xslt. Standards make life easier :-)

{-# LANGUAGE Arrows, PackageImports #-} 

import System.Environment ( getArgs )
import System.Exit (exitSuccess, exitWith, ExitCode(..))

import Control.Arrow
import "hxt" Text.XML.HXT.Core 
import "hxt" Text.XML.HXT.DOM.XmlKeywords 
import "hxt-xslt" Text.XML.HXT.XSLT.XsltArrows
import "hxt" Text.XML.HXT.Arrow.XmlState.TraceHandling (withTraceLevel)

process :: String -> String -> IO [String]
process xslStylesheetPath xmlDocPath = do

    -- compile stylesheet

    compiledStyleSheetResults <- runX $ 
        arr (const xslStylesheetPath) 
        >>> readXSLTDoc [ withValidate yes, withInputEncoding utf8]   -- withTrace 2 
        >>> {- withTraceLevel 2 -} xsltCompileStylesheet

    case compiledStyleSheetResults of
         [] -> return ["error compiling " ++ xslStylesheetPath] 
         compiledStyleSheet : _ -> do

             -- apply compiled stylesheet to xml doc 

             runX $ arr (const xmlDocPath) 
                 >>> readXSLTDoc [ withValidate yes, withInputEncoding utf8] -- withTrace 2
                 >>> xsltApplyStylesheet compiledStyleSheet
                 >>> writeDocumentToString [withOutputEncoding utf8, 
                                            withXmlPi yes, withIndent yes]

-- readXSLTDoc from internals of module Text.XML.HXT.XSLT.XsltArrows

readXSLTDoc :: SysConfigList -> IOSArrow String XmlTree
readXSLTDoc options
    = readFromDocument (options ++ defaultOptions)
    where
    defaultOptions
        = [ withCheckNamespaces yes
          , withValidate        no
          , withPreserveComment no
          ]         

main = do
 args <- getArgs
 case args of 
   [arg1, arg2] -> do
       results <- process arg1 arg2
       case results of
            [] -> putStrLn "errors"
            result : _ -> putStrLn result

       exitSuccess

   _ -> do 
            putStrLn "missing parameters: xslStylesheetPath xmlDocPath"
            exitWith $ ExitFailure 1

with XSL file "mystyle.xsl"

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
  <xsl:for-each select="document">
    <xsl:copy>
      <xsl:call-template name="myloop">
        <xsl:with-param name="nesting" select="0"/>
      </xsl:call-template>
    </xsl:copy>
  </xsl:for-each>
</xsl:template>

<xsl:template name="myloop">
  <xsl:param name="nesting"/>

  <xsl:if test="title">
   <xsl:element name="{concat('h',string($nesting))}">
     <xsl:value-of select="title" /> 
   </xsl:element>
  </xsl:if> 

  <xsl:for-each select="section">
    <xsl:copy>
      <xsl:call-template name="myloop">
        <xsl:with-param name="nesting" select="$nesting+1"/>
      </xsl:call-template>
    </xsl:copy>
  </xsl:for-each>

</xsl:template>
</xsl:stylesheet>

with "yourdata.xml"

<?xml version="1.0" encoding="UTF-8"?>
<document>
    <section>
        <title>Title A</title>
        <section>
            <title>Title B</title>
        </section>
        <section>
            <title>Title C</title>
            <section>
                <title>Title D</title>
            </section>
        </section>
    </section>
</document>

running

runhaskell test.hs mystyle.xsl yourdata.xml

result:

<?xml version="1.0" encoding="UTF-8"?>
<document>
  <section>
    <h1>Title A</h1>
    <section>
      <h2>Title B</h2>
    </section>
    <section>
      <h2>Title C</h2>
      <section>
        <h3>Title D</h3>
      </section>
    </section>
  </section>
</document>

这篇关于使用&lt;节>&gt;的数目,用HXT转换节点。祖先节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆