Update text in an element - Effectively
我需要这里专家的帮助,以优化更新element中的字符串值的解决方案。我有这个xml文件作为输入...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?xml version="1.0" encoding="UTF-8"?> <FullRequest> <Header> <Looptimes>3</Looptimes> <SomeElement>blah!</SomeElement> <AnotherElement>blah!!</AnotherElement> </Header> <RequestDetail> <!-- Request Element is a string of fixed length (50 characters) --> <Request>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG AGAIN!</Request> <Request>THE TIME FOX JUMPED OVER THE LAZY DOG, PROGRESSED!</Request> <Request>OWING TO THE WIDESPREAD KNOWLEDGE OF THE PHRASE AN</Request> </RequestDetail> </FullRequest> |
"请求"元素中的偏移量5将是唯一的,并且可以交叉引用。 Q,T和G是上述请求中的ID。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?xml version="1.0" encoding="UTF-8"?> <FullResponse> <Header> <Looptimes>3</Looptimes> <SomeElement>blah!</SomeElement> <AnotherElement>blah!!</AnotherElement> </Header> <ResponseDetail> <!-- Response element repeats for 3 times as indicated by the value of Looptimes --> <!-- Id has a unique value --> <Response> <Id>Q</Id> <Value1>ABC</Value1> <Value2>XYZ</Value2> <Value3>FGK</Value3> </Response> <Response> <Id>T</Id> <Value1>123</Value1> <Value2>YOK</Value2> <Value3>DSL</Value3> </Response> <Response> <Id>G</Id> <Value1>BAT</Value1> <Value2>TKR</Value2> <Value3>LAF</Value3> </Response> </ResponseDetail> </FullResponse> |
采用上述xml,需要将偏移位置10、15和20分别替换为值Value1,Value2和Value3。
我有完成这项工作的XSL。不确定此解决方案对几千条包含5000个字符的记录(在此处显示为示例的Request元素中为50个字符)具有大约20个要编辑的位置的记录的效果如何。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:regexp="http://exslt.org/regular-expressions" exclude-result-prefixes="regexp"> <xsl:output omit-xml-declaration="no" indent="yes"/> <xsl:preserve-space elements="*"/> <xsl:variable name="WebResponse" select="document('local:///ic1-data.xml')"/> <xsl:template match="node() | @*"> <xsl:copy> <xsl:apply-templates select="node() | @*"/> </xsl:copy> </xsl:template> <xsl:template match="/FullRequest/RequestDetail/Request"> <xsl:variable name="currentLine" select="."/> <xsl:variable name="id" select="substring($currentLine,5,1)"/> <xsl:for-each select="$WebResponse/FullResponse/ResponseDetail/Response"> <xsl:variable name="ResId" select="Id"/> <xsl:if test="$id = $ResId"> <xsl:element name="{name()}"> <!-- Update Value1 --> <xsl:variable name="from" select="substring($currentLine,10,3)"/> <xsl:variable name="UpdatedValue1" select="regexp:replace($currentLine,$from,'',Value1)"/> <!-- Update Value2 --> <xsl:variable name="from2" select="substring($UpdatedValue1,15,3)"/> <xsl:variable name="UpdatedValue2" select="regexp:replace($UpdatedValue1,$from2,'',Value2)"/> <!-- Update Value3 --> <xsl:variable name="from3" select="substring($UpdatedValue2,20,3)"/> <xsl:value-of select="regexp:replace($UpdatedValue2,$from3,'',Value3)"/> </xsl:element> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet> |
示例输出为:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?xml version="1.0" encoding="UTF-8"?> <FullRequest> <Header> <Looptimes>3</Looptimes> <SomeElement>blah!</SomeElement> <AnotherElement>blah!!</AnotherElement> </Header> <RequestDetail> <Response>THE QUICKABCOWXYZOXFGKMPS OVER THE LAZY DOG AGAIN!</Response> <Response>THE TIME 123 JYOKEDDSLER THE LAZY DOG, PROGRESSED!</Response> <Response>OWING TO BAT WTKRSPLAFD KNOWLEDGE OF THE PHRASE AN</Response> </RequestDetail> </FullRequest> |
我只能使用XSLT 1.0
您能建议如何使它变得更好吗?
谢谢。
另一种更灵活的方法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:strip-space elements="*"/> <xsl:key name="kResponseById" match="Response" use="Id"/> <xsl:variable name="WebResponse" select="document('ic1-data.xml')"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="Request/text()"> <xsl:variable name="vCurrent" select="."/> <xsl:for-each select="$WebResponse"> <xsl:call-template name="replace"> <xsl:with-param name="pString" select="$vCurrent"/> <xsl:with-param name="pValues" select="key('kResponseById', substring($vCurrent,5,1) )/*[starts-with(local-name(),'Value')]"/> </xsl:call-template> </xsl:for-each> </xsl:template> <xsl:template name="replace"> <xsl:param name="pString"/> <xsl:param name="pValues"/> <xsl:choose> <xsl:when test="$pValues"> <xsl:variable name="pLimit" select="substring-after( local-name($pValues[1]), 'Value' ) * 5 + 4"/> <xsl:call-template name="replace"> <xsl:with-param name="pString" select="concat( substring($pString, 1, $pLimit), $pValues[1], substring($pString, $pLimit + 4) )"/> <xsl:with-param name="pValues" select="$pValues[position()!=1]"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$pString"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> |
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <FullRequest> <Header> <Looptimes>3</Looptimes> <SomeElement>blah!</SomeElement> <AnotherElement>blah!!</AnotherElement> </Header> <RequestDetail> <!-- Request Element is a string of fixed length (50 characters) --> <Request>THE QUICKABCOWXYZOXFGKMPS OVER THE LAZY DOG AGAIN!</Request> <Request>THE TIME 123 JYOKEDDSLER THE LAZY DOG, PROGRESSED!</Request> <Request>OWING TO BAT WTKRSPLAFD KNOWLEDGE OF THE PHRASE AN</Request> </RequestDetail> </FullRequest> |