我有这个字符串作为节点的值:
/TAG3/Tag 3 Value/TAG2/Tag2 Value/Tag2 Value 2/Tag 2 value 3/TAG4/Tag4 value/TAG1/Tag 1 value/Tag1 value 2/
如果我需要按照TAG号重新排列,就像下面的
/TAG1/Tag 1 value/Tag1 value 2/TAG2/Tag2 Value/Tag2 Value 2/Tag 2 value 3/TAG3/Tag 3 Value/TAG4/Tag4 value
或者像这样用标签分解
/TAG1/Tag 1 value/Tag1 value 2/
/TAG2/Tag2 Value/Tag2 Value 2/Tag 2 value 3/
/TAG3/Tag 3 Value/
/TAG4/Tag4 value/
每个字符串应该以'/'开始和结束,并且必须有关键字(例如'TAG1')和值(例如'TAG1')。'Tag1 value')组合,值可以是多个,但关键字只能是一个
顺便问一下,在XSLT 1.0中有可能做到这一点吗?输入XML:
<?xml version='1.0' encoding='UTF-8'?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn-sample">
<CustomerRecord>
<Statement>
<StmtId>123</StmtId>
<StmtDate>2013-08-16</StmtDate>
<AcctNumber>123456789</AcctNumber>
<Balance>
<Type>OP</Type>
<Amount>1.00</Amount>
<CreditOrDebit>DR</CreditOrDebit>
<Date>2013-08-15</Date>
</Balance>
<Balance>
<Type>CL</Type>
<Amount>2.00</Amount>
<CreditOrDebit>CR</CreditOrDebit>
<Date>2013-08-16</Date>
</Balance>
<Balance>
<Type>FW</Type>
<Amount>3.00</Amount>
<CreditOrDebit>CR</CreditOrDebit>
<Date>2013-08-17</Date>
</Balance>
<Entry>
<Amount>7778.70</Amount>
<CreditOrDebit>DR</CreditOrDebit>
<EntryDtls>
<TransactionDetails>
<Parties>
<!--Details can come like this format-->
<Customer>
<Name>Customer 1 Name</Name>
<Address>Address Line 1</Address>
</Customer>
<CustomerAcct>
<AcctName>Account Name 1</AcctName>
<AcctNumber>12345677</AcctNumber>
</CustomerAcct>
<!--Or this-->
<CustDetails>/CUST/Customer 1 Name/Address Line 1/ACCT/Account Name 1/12345677/BANK/Bank Name/Bank Address/</CustDetails>
</Parties>
<AddlInfo>
<Info1>Info 1</Info1>
<Info1>Info 2</Info1>
<Info1>Info 3</Info1>
</AddlInfo>
</TransactionDetails>
</EntryDtls>
</Entry>
</Statement>
</CustomerRecord>
</Document>
对于Description标签CStatement/CStatementLine/Description应该有这样的输出:
<?xml version="1.0" encoding="utf-8"?>
<Root> <!--should have no attribute-->
<CStatement>
<CStatementId>123</CStatementId>
<CStatementDate>2013-08-16</CStatementDate>
<AccountNumber>123456789</AccountNumber>
<OpeningBalance>-1.00</OpeningBalance>
<ClosingBalance>2.00</ClosingBalance>
<CStatementLine>
<DebitOrCredit>DR</DebitOrCredit>
<Amount>-7778.70</Amount>
<!--values below will be coming from
<CustDetails>/CUST/Customer 1 Name/Address Line 1/ACCT/Account Name 1/12345677/BANK/Bank Name/Bank Address/</CustDetails> if
<Customer>
<Name>Customer 1 Name</Name>
<Address>Address Line 1</Address>
</Customer>
<CustomerAcct>
<AcctName>Account Name 1</AcctName>
<AcctNumber>12345677</AcctNumber>
</CustomerAcct>
is not existing-->
<CustomerName>Customer 1 Name</CustomerName>
<CustomerAddress>Address Line 1</CustomerAddress>
<CustAccountName>Account Name</CustAccountName>
<CustomerBankAccount>12345677</CustomerBankAccount>
<Description>CUST+Customer 1 Name+Address Line 2+ACCT+Account Name 1+12345677+ADDL+Info 1+Info 2+Info 3</Description>
</CStatementLine>
</CStatement>
</Root>
谢谢你的帮助
恐怕这个问题太复杂了,无法在论坛的范围内轻松回答。尽管如此,我还是相信三个主要问题的解决方案:
- 从给定字符串中提取值;而
- 为每个值分配一个标签;和
- 排序结果值
可以显示。
给定以下测试输入:
<input>
<CustDetails>/ACCT/Account Name 1/12345677/BANK/Bank Name/Bank Address/CUST/Customer 1 Name/Address Line 1/</CustDetails>
</input>
:
XSLT 1.0<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:variable name="tags" select="'|CUST|BANK|ACCT|'"/>
<xsl:template match="input">
<!-- first pass -->
<xsl:variable name="values">
<xsl:call-template name="tokenize">
<!-- remove the opening slash -->
<xsl:with-param name="text" select="substring(CustDetails, 2, string-length(CustDetails))"/>
</xsl:call-template>
</xsl:variable>
<!-- output -->
<output>
<xsl:for-each select="exsl:node-set($values)/value">
<!-- sort by position of @tag in $tags -->
<xsl:sort select="string-length(substring-before($tags, concat('|', @tag, '|')))" data-type="number" order="ascending"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</output>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="'/'"/>
<xsl:param name="tag"/>
<xsl:if test="$text">
<xsl:variable name="token" select="substring-before($text, $delimiter)"/>
<xsl:choose>
<xsl:when test="contains($tags, concat('|', $token, '|'))">
<!-- new tag -->
<value tag="{$token}">
<xsl:value-of select="$token"/>
</value>
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
<xsl:with-param name="tag" select="$token"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<value tag="{$tag}">
<xsl:value-of select="$token"/>
</value>
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
<xsl:with-param name="tag" select="$tag"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
将返回:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<value tag="CUST">CUST</value>
<value tag="CUST">Customer 1 Name</value>
<value tag="CUST">Address Line 1</value>
<value tag="BANK">BANK</value>
<value tag="BANK">Bank Name</value>
<value tag="BANK">Bank Address</value>
<value tag="ACCT">ACCT</value>
<value tag="ACCT">Account Name 1</value>
<value tag="ACCT">12345677</value>
</output>
您只需要修改输出,而不是原样复制值,将其放置在文本字符串中。