2008-09-18 60 views

回答

2

你可以用XSLT做的一些事情你也可以通过某种形式的'搜索&替换'来完成。这完全取决于问题的复杂程度以及您希望实施解决方案的“通用性”。为使您自己的示例稍微更通用:

xml.replaceFirst("<Mobiltlf>[^<]*</Mobiltlf>", '<Mobiltlf>32165487</Mobiltlf>') 

您选择的解决方案由您决定。根据我自己的经验(对于非常简单的问题),使用简单的字符串查找比使用正则表达式要快得多,这比使用完整的XSLT转换(实际上有意义)要快。

1

一些疯狂的编码后,我看到了光,做了这样的

import org.custommonkey.xmlunit.Diff 
import org.custommonkey.xmlunit.XMLUnit 

def input = '''<root><data></data></root>''' 
def expectedResult = '''<root><data>value</data></root>''' 

def xml = new XmlParser().parseText(input) 

def p = xml.'**'.data 
p.each{it.value="value"} 

def writer = new StringWriter() 
new XmlNodePrinter(new PrintWriter(writer)).print(xml) 
def result = writer.toString() 

XMLUnit.setIgnoreWhitespace(true) 
def xmlDiff = new Diff(result, expectedResult) 
assert xmlDiff.identical() 

不幸的是这将不保留意见和元数据等,从原始的XML文档,所以我将不得不另谋出路

1

我DOMCategory做了一些一些测试和它几乎工作。我可以让替换发生,但一些与信息相关的评论消失。在这样一个源

def rtv = { xml, tag, value -> 
    def doc  = DOMBuilder.parse(new StringReader(xml)) 
    def root = doc.documentElement 
    use(DOMCategory) { root.'**'."$tag".each{it.value=value} } 
    return DOMUtil.serialize(root)  
} 

:我使用的方法是这样

<?xml version="1.0" encoding="utf-8"?> 
<?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:FA_Ansoegning:http---ementor-dk-application-2007-06-22-" href="manifest.xsf" solutionVersion="1.0.0.14" productVersion="12.0.0" PIVersion="1.0.0.0" ?> 
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.2"?> 
<application:FA_Ansoegning xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:application="http://corp.dk/application/2007/06/22/" 
xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" 
xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/200 8-04-14T14:31:48"> 
    <Mobiltlf></Mobiltlf> 
    <E-mail-adresse></E-mail-adresse> 
</application:FA_Ansoegning> 

从结果中唯一缺少的是< mso-从结果行?任何人有这样的想法?

0

对我来说,实际的副本&搜索&替换看起来像XSLT样式表的完美工作。在XSLT中,只需复制所有内容(包括有问题的项目)就可以了,只需将数据插入需要的地方即可。您可以通过XSL参数传递数据的特定值,也可以动态修改样式表本身(如果您在Groovy程序中包含字符串)。调用这个XSLT来转换Groovy中的文档非常简单。

我赶紧鹅卵石以下Groovy脚本在一起(但我毫不怀疑它甚至可以更简单/紧凑写入):

import javax.xml.transform.TransformerFactory 
import javax.xml.transform.stream.StreamResult 
import javax.xml.transform.stream.StreamSource 

def xml = """ 
<?xml version="1.0" encoding="utf-8"?> 
<?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:FA_Ansoegning:http---ementor-dk-application-2007-06-22-" href="manifest.xsf" solutionVersion="1.0.0.14" productVersion="12.0.0" PIVersion="1.0.0.0" ?> 
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.2"?> 
<application:FA_Ansoegning xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:application="http://ementor.dk/application/2007/06/22/" 
xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" 
xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/200 8-04-14T14:31:48"> 
    <Mobiltlf></Mobiltlf> 
    <E-mail-adresse></E-mail-adresse> 
</application:FA_Ansoegning> 
""".trim() 

def xslt = """ 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:param name="mobil" select="'***dummy***'"/> 
    <xsl:param name="email" select="'***dummy***'"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Mobiltlf"> 
     <xsl:copy> 
      <xsl:value-of select="\$mobil"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="E-mail-adresse"> 
     <xsl:copy> 
      <xsl:value-of select="\$email"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 
""".trim() 

def factory = TransformerFactory.newInstance() 
def transformer = factory.newTransformer(new StreamSource(new StringReader(xslt))) 

transformer.setParameter('mobil', '1234567890') 
transformer.setParameter('email', '[email protected]') 

transformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(System.out)) 

运行此脚本生成:

<?xml version="1.0" encoding="UTF-8"?><?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:FA_Ansoegning:http---ementor-dk-application-2007-06-22-" href="manifest.xsf" solutionVersion="1.0.0.14" productVersion="12.0.0" PIVersion="1.0.0.0" ?> 
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.2"?> 
<application:FA_Ansoegning xmlns:application="http://ementor.dk/application/2007/06/22/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/200 8-04-14T14:31:48"> 
    <Mobiltlf>1234567890</Mobiltlf> 
    <E-mail-adresse>[email protected]</E-mail-adresse> 
</application:FA_Ansoegning> 
1

这就是迄今为止最好的答案,它给出了正确的结果,所以我会接受答案:) 但是,这对我来说有点过大。我想我最好解释,替代是:

xml.replace("<Mobiltlf></Mobiltlf>", <Mobiltlf>32165487</Mobiltlf>") 

但这不是很xml'y所以我想我会寻找替代品。另外,我无法确定第一个标签是否一直是空的。

0

太棒了!非常感谢您的帮助:)

这样就以更简洁更简单的方式解决了我的问题。它结束了看起来像这样:

def rtv = { xmlSource, tagName, newValue -> 
    regex = "<$tagName>[^<]*</$tagName>" 
    replacement = "<$tagName>${newValue}</$tagName>" 
    xmlSource = xmlSource.replaceAll(regex, replacement) 
    return xmlSource 
} 

input = rtv(input, "Mobiltlf", "32165487") 
input = rtv(input, "E-mail-adresse", "[email protected]") 
println input 

因为我给这对我们的测试人员在他们的测试工具了SoapUI使用,我已经试过“包装”它,使他们更容易复制和糊。

这是对我来说已经足够了,但它是完美的,如果我们可以添加更多的“扭曲”

比方说在它的输入有这个...

<Mobiltlf type="national" anotherattribute="value"></Mobiltlf> 

..我们希望保留这两个属性,即使我们取代了这个值。有没有办法使用regexp呢?

1

要保留的属性只需要修改你的小程序是这样的(我已经包含了样本源进行测试):

def input = """ 
<?xml version="1.0" encoding="utf-8"?> 
<?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:FA_Ansoegning:http---ementor-dk-application-2007-06-22-" href="manifest.xsf" solutionVersion="1.0.0.14" productVersion="12.0.0" PIVersion="1.0.0.0" ?> 
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.2"?> 
<application:FA_Ansoegning xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:application="http://ementor.dk/application/2007/06/22/" 
xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" 
xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/200 8-04-14T14:31:48"> 
    <Mobiltlf type="national" anotherattribute="value"></Mobiltlf> 
    <E-mail-adresse attr="whatever"></E-mail-adresse> 
</application:FA_Ansoegning> 
""".trim() 

def rtv = { xmlSource, tagName, newValue -> 
    regex = "(<$tagName[^>]*>)([^<]*)(</$tagName>)" 
    replacement = "\$1${newValue}\$3" 
    xmlSource = xmlSource.replaceAll(regex, replacement) 
    return xmlSource 
} 

input = rtv(input, "Mobiltlf", "32165487") 
input = rtv(input, "E-mail-adresse", "[email protected]") 
println input 

运行此脚本生成:

<?xml version="1.0" encoding="utf-8"?> 
<?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:FA_Ansoegning:http---ementor-dk-application-2007-06-22-" href="manifest.xsf" solutionVersion="1.0.0.14" productVersion="12.0.0" PIVersion="1.0.0.0" ?> 
<?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.2"?> 
<application:FA_Ansoegning xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:application="http://ementor.dk/application/2007/06/22/" 
xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" 
xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/200 8-04-14T14:31:48"> 
    <Mobiltlf type="national" anotherattribute="value">32165487</Mobiltlf> 
    <E-mail-adresse attr="whatever">[email protected]</E-mail-adresse> 
</application:FA_Ansoegning> 

注意,匹配正则表达式现在包含3个捕获组:(1)开始标记(包括属性),(2)无论您的标记的“旧”内容和(3)结束标记。替换字符串通过$ i语法引用这些捕获的组(使用反斜杠在GString中转义它们)。只是一个提示:正则表达式是非常强大的动物,熟悉它们真的很值得;-)。

相关问题