使用<节>>的数目,用HXT转换节点。祖先节点 [英] Transform nodes with HXT using the number of <section> ancestor nodes
问题描述
我正在用 Input.xml Output.xml 我可以将所有 h1
, h2来替换所有
title code>,...,
s使用类似的东西 h6
元素,具体取决于有多少祖先是部分
元素。示例输入/输出:
<文件>
<节>
< title>标题A< / title>
<节>
< title>标题B< / title>
< / section>
<节>
< title>标题C< / title>
<节>
< title>标题D< / title>
< / section>
< / section>
< / section>
< / document>
< document>
<节>
< h1>标题A< / h1>
<节>
< h2>标题B< / h2>
< / section>
<节>
< h2>标题C< / h2>
<节>
< h3>标题D< / h3>
< / section>
< / section>
< / section>
< / document>
title
code> h1
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 title
s with h1
s 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>
这篇关于使用<节>>的数目,用HXT转换节点。祖先节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!