所以我们的数据在子/父中有xmlns=
,它阻止了孩子的价值被XSLT更新
示例数据(请注意,在xmlns="http://example.com/abc-artifact"
之后,我故意从第二条记录中删除了<Letter
,以说明导致错误的原因是什么?:
<Documents>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersonalData>
<Name>JACK</Name>
</PersonalData>
<DocumentXml>
<Letter xmlns="http://example.com/abc-artifact" xsi:schemaLocation="http://example.com/abc-artifact.xsd" xsi:type="LetterType">
<HeaderRecord>
<DateOfBirth>1971-11-07</DateOfBirth>
</HeaderRecord>
</Letter>
</DocumentXml>
</Document>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersonalData>
<Name>TONJA</Name>
</PersonalData>
<DocumentXml>
<Letter xsi:schemaLocation="http://example.com/abc-artifact.xsd" xsi:type="LetterType">
<HeaderRecord>
<DateOfBirth>1974-22-10</DateOfBirth>
</HeaderRecord>
</Letter>
</DocumentXml>
</Document>
</Documents>
XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="DateOfBirth">
<xsl:copy>
<xsl:text>NewDOB</xsl:text>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出
<Documents>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersonalData>
<Name>JACK</Name>
</PersonalData>
<DocumentXml>
<Letter xmlns="http://example.com/abc-artifact">
<HeaderRecord>
<DateOfBirth>1971-11-07</DateOfBirth>
</HeaderRecord>
</Letter>
</DocumentXml>
</Document>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersonalData>
<Name>TONJA</Name>
</PersonalData>
<DocumentXml>
<Letter>
<HeaderRecord>
<DateOfBirth>NewDOB</DateOfBirth>
</HeaderRecord>
</Letter>
</DocumentXml>
</Document>
</Documents>
所以你可以看到<DateOfBirth>
更新了第二条记录,但不是第一条记录。我们的团队无法控制数据,也无法要求他们删除xmlns="http://example.com/abc-artifact"
。有什么建议?感谢
答案 0 :(得分:2)
如果您的输入中有默认命名空间(未加前缀的命名空间),则可以将该命名空间uri绑定到XSLT中的前缀,以使其正确匹配。
此外,xsl:copy
将为您处理命名空间。
示例...
XML输入(将命名空间添加回第二个Letter
)
<Documents>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersonalData>
<Name>JACK</Name>
</PersonalData>
<DocumentXml>
<Letter xmlns="http://example.com/abc-artifact" xsi:schemaLocation="http://example.com/abc-artifact.xsd" xsi:type="LetterType">
<HeaderRecord>
<DateOfBirth>1971-11-07</DateOfBirth>
</HeaderRecord>
</Letter>
</DocumentXml>
</Document>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersonalData>
<Name>TONJA</Name>
</PersonalData>
<DocumentXml>
<Letter xmlns="http://example.com/abc-artifact" xsi:schemaLocation="http://example.com/abc-artifact.xsd" xsi:type="LetterType">
<HeaderRecord>
<DateOfBirth>1974-22-10</DateOfBirth>
</HeaderRecord>
</Letter>
</DocumentXml>
</Document>
</Documents>
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:abc="http://example.com/abc-artifact">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="abc:DateOfBirth">
<xsl:copy>
<xsl:text>NewDOB</xsl:text>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XML输出
<Documents>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersonalData>
<Name>JACK</Name>
</PersonalData>
<DocumentXml>
<Letter xmlns="http://example.com/abc-artifact" xsi:schemaLocation="http://example.com/abc-artifact.xsd" xsi:type="LetterType">
<HeaderRecord>
<DateOfBirth>NewDOB</DateOfBirth>
</HeaderRecord>
</Letter>
</DocumentXml>
</Document>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersonalData>
<Name>TONJA</Name>
</PersonalData>
<DocumentXml>
<Letter xmlns="http://example.com/abc-artifact" xsi:schemaLocation="http://example.com/abc-artifact.xsd" xsi:type="LetterType">
<HeaderRecord>
<DateOfBirth>NewDOB</DateOfBirth>
</HeaderRecord>
</Letter>
</DocumentXml>
</Document>
</Documents>
此外,如果您只是更改文本,您可以专门匹配它,并让身份变换处理元素/属性......
<xsl:template match="abc:DateOfBirth/text()">
<xsl:text>NewDOB</xsl:text>>
</xsl:template>
答案 1 :(得分:1)
我了解您遇到的问题是由于名称空间。
您可以添加在xml中删除的命名空间。
以下是根据您的要求修改的 xslt 。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//*[local-name()='DateOfBirth']">
<xsl:element name="DateOfBirth" namespace="http://example.com/abc-artifact">
<xsl:text>NewDOB</xsl:text>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
您会看到以下输出xml
<?xml version="1.0" encoding="UTF-8"?>
<Documents>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersonalData>
<Name>JACK</Name>
</PersonalData>
<DocumentXml>
<Letter xmlns="http://example.com/abc-artifact" xsi:schemaLocation="http://example.com/abc-artifact.xsd" xsi:type="LetterType">
<HeaderRecord>
<DateOfBirth>NewDOB</DateOfBirth>
</HeaderRecord>
</Letter>
</DocumentXml>
</Document>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersonalData>
<Name>TONJA</Name>
</PersonalData>
<DocumentXml>
<Letter xmlns="http://example.com/abc-artifact" xsi:schemaLocation="http://example.com/abc-artifact.xsd" xsi:type="LetterType">
<HeaderRecord>
<DateOfBirth>NewDOB</DateOfBirth>
</HeaderRecord>
</Letter>
</DocumentXml>
</Document>
</Documents>
希望你试图解决这个问题,现在看看预期的输出。
编辑:您可以看到处理名称空间的第二个模板中的更改
答案 2 :(得分:1)
您的模板:
<xsl:template match="DateOfBirth">
不匹配命名空间中的DateOfBirth
个元素。为此,您必须使用元素的完全限定名称。首先,声明命名空间并将其绑定到前缀,然后在寻址元素时使用该前缀:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:abc="http://example.com/abc-artifact" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="abc:DateOfBirth">
<xsl:copy>
<xsl:text>NewDOB</xsl:text>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>