2014-09-01 28 views
1

的任务是摆脱任何非数字字符在以下CustomerIdentity元素的XML文件中:更改文本(摆脱非数字字符的)

<ns2:TaxAtSource institutionID="#SG"> 
    <ns2:CantonID>SG</ns2:CantonID> 
    <ns2:CustomerIdentity>CHE123.456 </ns2:CustomerIdentity> 
</ns2:TaxAtSource> 

我试过SED (这将是优雅的,但由于非数字字符可以在CustomerIdentity标签之间的任何地方,因此正则表达式会变得有点多毛)。我也尝试过XSLT,但命名空间ns2在识别标记(未引用的命名空间)时遇到了麻烦。 因此,如果任何人有一个有效的解决方案来处理XML文件,如下所示(其余的应该是不变):

<ns2:TaxAtSource institutionID="#SG"> 
    <ns2:CantonID>SG</ns2:CantonID> 
    <ns2:CustomerIdentity>123456</ns2:CustomerIdentity> 
</ns2:TaxAtSource> 

这将是非常赞赏。一位同事建议使用AWK或红宝石,但我认为这也归结为正则表达式。

编辑:我已经尝试了以下XSLT从xsl remove all non-numeric characters and leading 1

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 

<xsl:template match="text()"> 
    <xsl:variable name="vnumsOnly" select= 
    "translate(., translate(.,'',''), '') 
    "/> 

    <xsl:value-of select= 
    "substring($vnumsOnly, (substring($vnumsOnly,1,1)='1') +1)"/> 
</xsl:template> 
</xsl:stylesheet> 

,但没有相当锻炼。

+1

你所说的 “无引用的命名空间” 是什么意思?如果名称空间前缀没有定义,那么您的数据不符合格式良好的XML,并且不属于XML文件。此外,XSLT不会接受它作为输入。 – 2014-09-01 11:15:07

+0

@codeninja命名空间文件? – 2014-09-01 11:50:03

+0

@mathis,谢谢你指出我的错误,我删除了我的评论。我认为这可能是dtd问题,所以我提到重新确认文件目录。但现在我意识到它的错误/非声明的命名空间声明在根目录 – 2014-09-01 11:59:40

回答

2

我从你自己的答案引用:

As you already mentioned it just needs to be well-formed, so the "faked" namespace declaration works out. I have to use version 1.0, as my xsltproc seems to only support that version:

不是真的,看看here。你看到任何非数字字符被删除?


实际上,它恰好相反。它是的前缀,它是任意的,以及唯一标识名称空间的完整名称空间声明。换句话说,元件

<ns2:CustomerIdentity> 

其中的xmlns:ns2的= “swissdec.ch/schema/sd/20130514/SalaryDeclaration”

<ns2:CustomerIdentity> 

其中的xmlns:ns2的=“WWW .testing.com“

不同的元素,就一个XML解析器而言。另一方面,

<ns2:CustomerIdentity> 

其中xmlns:ns2 =“swissdec。CH /模式/ SD/20130514/SalaryDeclaration”

<other:CustomerIdentity> 

其中的xmlns:其他= “swissdec.ch/schema/sd/2013051/SalaryDeclaration”

识别相同元件。因此,当您转换XML文档并需要访问单个元素时,您需要声明名称空间与源文档中的名称空间完全相同,但可以为其选择另一个前缀。

样式

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0" 
    xmlns:ns2="swissdec.ch/schema/sd/20130514/SalaryDeclaration"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 

    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="ns2:CustomerIdentity/text()"> 
     <xsl:value-of 
      select="translate(., translate(.,'',''), '')"/> 
    </xsl:template> 
</xsl:transform> 

XML输入

<ns2:TaxAtSource institutionID="#SG" 
    xmlns:ns2="swissdec.ch/schema/sd/20130514/SalaryDeclaration"> 
    <ns2:CantonID>SG</ns2:CantonID> 
    <ns2:CustomerIdentity>CHE123.456 </ns2:CustomerIdentity> 
</ns2:TaxAtSource> 

XML输出

<?xml version="1.0" encoding="UTF-8"?> 
<ns2:TaxAtSource 
    xmlns:ns2="swissdec.ch/schema/sd/20130514/SalaryDeclaration" 
    institutionID="#SG"> 
    <ns2:CantonID>SG</ns2:CantonID> 
    <ns2:CustomerIdentity>123456</ns2:CustomerIdentity> 
</ns2:TaxAtSource> 
+0

你是对的,我的解决方案不仅从_all_标签中删除非数字CustomerIdentity ...我的不好。哦,谢谢你的帮助! – 2014-09-01 13:14:02

+0

好的,现在更好一个:http://xsltransform.net/eiZQaEV/14似乎工作,但只有在线,我的处理器不会更改值。 – 2014-09-01 13:21:13

+0

@Chrispingu好多了!我添加了一行([here](http://xsltransform.net/eiZQaEV/15)),现在没关系。你在使用什么处理器? – 2014-09-01 13:25:39

1

您可以使用XSLT 2.0的替换函数;

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" 
xmlns:ns2="www.testing.com" 
exclude-result-prefixes="ns2"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:template match="ns2:CustomerIdentity"> 
     <ns2:CustomerIdentity> 
      <xsl:value-of select='replace(., "[a-zA-Z. ]+","")'/> 
     </ns2:CustomerIdentity> 
    </xsl:template> 

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

如果XML输入中没有名称空间声明,则不会有任何样式表工作。你假设'xmlns:ns2 =“www.testing.com”'但似乎没有这样的声明。 – 2014-09-01 12:22:58

+0

这不会与我的xsltproc工具(perl)兼容,因为它似乎只支持版本1.0特性=>编译错误:file transform.xsl第3行元素样式表 xsl:版本:仅支持1.0特性 – 2014-09-01 12:41:33

0

正如我编辑自己的问题,我看到了一种方式(也感谢xsl remove all non-numeric characters and leading 1)。正如你已经提到的那样,它只需要格式良好,所以“伪造”的命名空间声明就可以实现。我必须使用1.0版本,因为我xsltproc的似乎只支持版本:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
xmlns:ns2="www.testing.com" exclude-result-prefixes="ns2"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="text()"> 
     <xsl:variable name="vnumsOnly" select= 
     "translate(., translate(.,'',''), '') 
     "/> 

     <xsl:value-of select= 
     "substring($vnumsOnly, (substring($vnumsOnly,1,1)='1') +1)"/> 
    </xsl:template> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

感谢指导我到正确的方向!

+0

并非如此。请看我的答案,我试图解释一些事情。 – 2014-09-01 13:07:42

+0

撇开已经指出的其他问题,这个尝试的解决方案从代码的来源中接收不相关的细节;提出的问题没有任何理由去除前导'1'。 – 2014-09-02 02:35:35